Merge "TBR Revert "js: Use cache for blessings between go and js""
diff --git a/.gitignore b/.gitignore
index 5854afc..cd0b069 100644
--- a/.gitignore
+++ b/.gitignore
@@ -14,7 +14,6 @@
go/bin
xunit.xml
tmp
-.idea
# Vanadium
/.v23
diff --git a/src/gen-vdl/v.io/x/ref/services/wspr/internal/app/index.js b/src/gen-vdl/v.io/x/ref/services/wspr/internal/app/index.js
index 8ff3aad..5850954 100644
--- a/src/gen-vdl/v.io/x/ref/services/wspr/internal/app/index.js
+++ b/src/gen-vdl/v.io/x/ref/services/wspr/internal/app/index.js
@@ -22,6 +22,7 @@
// Types:
var _type1 = new vdl.Type();
+var _type10 = new vdl.Type();
var _type2 = new vdl.Type();
var _type3 = new vdl.Type();
var _type4 = new vdl.Type();
@@ -40,6 +41,9 @@
_type1.kind = vdl.kind.LIST;
_type1.name = "";
_type1.elem = _typeRpcCallOption;
+_type10.kind = vdl.kind.LIST;
+_type10.name = "";
+_type10.elem = new principal.BlessingsHandle()._type;
_type2.kind = vdl.kind.LIST;
_type2.name = "";
_type2.elem = new security.BlessingPattern()._type;
@@ -52,19 +56,19 @@
_type5.kind = vdl.kind.LIST;
_type5.name = "";
_type5.elem = new security.Caveat()._type;
-_type6.kind = vdl.kind.LIST;
+_type6.kind = vdl.kind.OPTIONAL;
_type6.name = "";
-_type6.elem = vdl.types.STRING;
-_type7.kind = vdl.kind.MAP;
+_type6.elem = new principal.JsBlessings()._type;
+_type7.kind = vdl.kind.LIST;
_type7.name = "";
-_type7.elem = new principal.BlessingsId()._type;
-_type7.key = new security.BlessingPattern()._type;
-_type8.kind = vdl.kind.LIST;
+_type7.elem = vdl.types.STRING;
+_type8.kind = vdl.kind.MAP;
_type8.name = "";
-_type8.elem = new signature.Interface()._type;
+_type8.elem = _type6;
+_type8.key = new security.BlessingPattern()._type;
_type9.kind = vdl.kind.LIST;
_type9.name = "";
-_type9.elem = new principal.BlessingsHandle()._type;
+_type9.elem = new signature.Interface()._type;
_typeGranterHandle.kind = vdl.kind.INT32;
_typeGranterHandle.name = "v.io/x/ref/services/wspr/internal/app.GranterHandle";
_typeGranterRequest.kind = vdl.kind.STRUCT;
@@ -86,6 +90,7 @@
_typeRpcServerOption.name = "v.io/x/ref/services/wspr/internal/app.RpcServerOption";
_typeRpcServerOption.fields = [{name: "IsLeaf", type: vdl.types.BOOL}, {name: "ServesMountTable", type: vdl.types.BOOL}];
_type1.freeze();
+_type10.freeze();
_type2.freeze();
_type3.freeze();
_type4.freeze();
@@ -381,9 +386,14 @@
},
],
outArgs: [{
- name: '',
+ name: 'publicKeyOut',
doc: "",
- type: new principal.BlessingsId()._type
+ type: vdl.types.STRING
+ },
+ {
+ name: 'handleOut',
+ doc: "",
+ type: new principal.BlessingsHandle()._type
},
],
inStream: null,
@@ -407,9 +417,14 @@
},
],
outArgs: [{
- name: '',
+ name: 'publicKeyOut',
doc: "",
- type: new principal.BlessingsId()._type
+ type: vdl.types.STRING
+ },
+ {
+ name: 'handleOut',
+ doc: "",
+ type: new principal.BlessingsHandle()._type
},
],
inStream: null,
@@ -451,7 +466,7 @@
outArgs: [{
name: '',
doc: "",
- type: new principal.BlessingsId()._type
+ type: _type6
},
],
inStream: null,
@@ -466,13 +481,13 @@
inArgs: [{
name: 'peerBlessings',
doc: "",
- type: _type6
+ type: _type7
},
],
outArgs: [{
name: '',
doc: "",
- type: new principal.BlessingsId()._type
+ type: _type6
},
],
inStream: null,
@@ -504,7 +519,7 @@
outArgs: [{
name: '',
doc: "",
- type: new principal.BlessingsId()._type
+ type: _type6
},
],
inStream: null,
@@ -536,7 +551,7 @@
outArgs: [{
name: '',
doc: "",
- type: _type7
+ type: _type8
},
],
inStream: null,
@@ -578,7 +593,7 @@
outArgs: [{
name: '',
doc: "",
- type: _type6
+ type: _type7
},
],
inStream: null,
@@ -599,7 +614,7 @@
outArgs: [{
name: '',
doc: "",
- type: _type8
+ type: _type9
},
],
inStream: null,
@@ -614,13 +629,13 @@
inArgs: [{
name: 'toJoin',
doc: "",
- type: _type9
+ type: _type10
},
],
outArgs: [{
name: '',
doc: "",
- type: new principal.BlessingsId()._type
+ type: _type6
},
],
inStream: null,
diff --git a/src/gen-vdl/v.io/x/ref/services/wspr/internal/principal/index.js b/src/gen-vdl/v.io/x/ref/services/wspr/internal/principal/index.js
index f11c056..a799f10 100644
--- a/src/gen-vdl/v.io/x/ref/services/wspr/internal/principal/index.js
+++ b/src/gen-vdl/v.io/x/ref/services/wspr/internal/principal/index.js
@@ -16,39 +16,16 @@
// Types:
-var _typeBlessingsCacheAddMessage = new vdl.Type();
-var _typeBlessingsCacheDeleteMessage = new vdl.Type();
-var _typeBlessingsCacheMessage = new vdl.Type();
var _typeBlessingsHandle = new vdl.Type();
-var _typeBlessingsId = new vdl.Type();
var _typeJsBlessings = new vdl.Type();
-_typeBlessingsCacheAddMessage.kind = vdl.kind.STRUCT;
-_typeBlessingsCacheAddMessage.name = "v.io/x/ref/services/wspr/internal/principal.BlessingsCacheAddMessage";
-_typeBlessingsCacheAddMessage.fields = [{name: "CacheId", type: _typeBlessingsId}, {name: "Blessings", type: _typeJsBlessings}];
-_typeBlessingsCacheDeleteMessage.kind = vdl.kind.STRUCT;
-_typeBlessingsCacheDeleteMessage.name = "v.io/x/ref/services/wspr/internal/principal.BlessingsCacheDeleteMessage";
-_typeBlessingsCacheDeleteMessage.fields = [{name: "CacheId", type: _typeBlessingsId}, {name: "DeleteAfter", type: vdl.types.UINT32}];
-_typeBlessingsCacheMessage.kind = vdl.kind.UNION;
-_typeBlessingsCacheMessage.name = "v.io/x/ref/services/wspr/internal/principal.BlessingsCacheMessage";
-_typeBlessingsCacheMessage.fields = [{name: "Add", type: _typeBlessingsCacheAddMessage}, {name: "Delete", type: _typeBlessingsCacheDeleteMessage}];
_typeBlessingsHandle.kind = vdl.kind.INT32;
_typeBlessingsHandle.name = "v.io/x/ref/services/wspr/internal/principal.BlessingsHandle";
-_typeBlessingsId.kind = vdl.kind.UINT32;
-_typeBlessingsId.name = "v.io/x/ref/services/wspr/internal/principal.BlessingsId";
_typeJsBlessings.kind = vdl.kind.STRUCT;
_typeJsBlessings.name = "v.io/x/ref/services/wspr/internal/principal.JsBlessings";
_typeJsBlessings.fields = [{name: "Handle", type: _typeBlessingsHandle}, {name: "PublicKey", type: vdl.types.STRING}];
-_typeBlessingsCacheAddMessage.freeze();
-_typeBlessingsCacheDeleteMessage.freeze();
-_typeBlessingsCacheMessage.freeze();
_typeBlessingsHandle.freeze();
-_typeBlessingsId.freeze();
_typeJsBlessings.freeze();
-module.exports.BlessingsCacheAddMessage = (vdl.registry.lookupOrCreateConstructor(_typeBlessingsCacheAddMessage));
-module.exports.BlessingsCacheDeleteMessage = (vdl.registry.lookupOrCreateConstructor(_typeBlessingsCacheDeleteMessage));
-module.exports.BlessingsCacheMessage = (vdl.registry.lookupOrCreateConstructor(_typeBlessingsCacheMessage));
module.exports.BlessingsHandle = (vdl.registry.lookupOrCreateConstructor(_typeBlessingsHandle));
-module.exports.BlessingsId = (vdl.registry.lookupOrCreateConstructor(_typeBlessingsId));
module.exports.JsBlessings = (vdl.registry.lookupOrCreateConstructor(_typeJsBlessings));
@@ -67,8 +44,6 @@
// Services:
-
-
diff --git a/src/gen-vdl/v.io/x/ref/services/wspr/internal/rpc/server/index.js b/src/gen-vdl/v.io/x/ref/services/wspr/internal/rpc/server/index.js
index 4d2cfe6..b27766f 100644
--- a/src/gen-vdl/v.io/x/ref/services/wspr/internal/rpc/server/index.js
+++ b/src/gen-vdl/v.io/x/ref/services/wspr/internal/rpc/server/index.js
@@ -28,6 +28,7 @@
var _type4 = new vdl.Type();
var _type5 = new vdl.Type();
var _type6 = new vdl.Type();
+var _type7 = new vdl.Type();
var _typeAuthReply = new vdl.Type();
var _typeCaveatValidationRequest = new vdl.Type();
var _typeCaveatValidationResponse = new vdl.Type();
@@ -51,9 +52,12 @@
_type5.kind = vdl.kind.LIST;
_type5.name = "";
_type5.elem = vdl.types.ERROR;
-_type6.kind = vdl.kind.LIST;
+_type6.kind = vdl.kind.OPTIONAL;
_type6.name = "";
-_type6.elem = new signature.Interface()._type;
+_type6.elem = new principal.JsBlessings()._type;
+_type7.kind = vdl.kind.LIST;
+_type7.name = "";
+_type7.elem = new signature.Interface()._type;
_typeAuthReply.kind = vdl.kind.STRUCT;
_typeAuthReply.name = "v.io/x/ref/services/wspr/internal/rpc/server.AuthReply";
_typeAuthReply.fields = [{name: "Err", type: vdl.types.ERROR}];
@@ -68,22 +72,23 @@
_typeContext.fields = [{name: "Language", type: vdl.types.STRING}];
_typeLookupReply.kind = vdl.kind.STRUCT;
_typeLookupReply.name = "v.io/x/ref/services/wspr/internal/rpc/server.LookupReply";
-_typeLookupReply.fields = [{name: "Handle", type: vdl.types.INT32}, {name: "HasAuthorizer", type: vdl.types.BOOL}, {name: "HasGlobber", type: vdl.types.BOOL}, {name: "Signature", type: _type6}, {name: "Err", type: vdl.types.ERROR}];
+_typeLookupReply.fields = [{name: "Handle", type: vdl.types.INT32}, {name: "HasAuthorizer", type: vdl.types.BOOL}, {name: "HasGlobber", type: vdl.types.BOOL}, {name: "Signature", type: _type7}, {name: "Err", type: vdl.types.ERROR}];
_typeSecurityCall.kind = vdl.kind.STRUCT;
_typeSecurityCall.name = "v.io/x/ref/services/wspr/internal/rpc/server.SecurityCall";
-_typeSecurityCall.fields = [{name: "Method", type: vdl.types.STRING}, {name: "Suffix", type: vdl.types.STRING}, {name: "MethodTags", type: _type1}, {name: "LocalBlessings", type: new principal.BlessingsId()._type}, {name: "LocalBlessingStrings", type: _type2}, {name: "RemoteBlessings", type: new principal.BlessingsId()._type}, {name: "RemoteBlessingStrings", type: _type2}, {name: "LocalEndpoint", type: vdl.types.STRING}, {name: "RemoteEndpoint", type: vdl.types.STRING}];
+_typeSecurityCall.fields = [{name: "Method", type: vdl.types.STRING}, {name: "Suffix", type: vdl.types.STRING}, {name: "MethodTags", type: _type1}, {name: "LocalBlessings", type: new principal.JsBlessings()._type}, {name: "LocalBlessingStrings", type: _type2}, {name: "RemoteBlessings", type: new principal.JsBlessings()._type}, {name: "RemoteBlessingStrings", type: _type2}, {name: "LocalEndpoint", type: vdl.types.STRING}, {name: "RemoteEndpoint", type: vdl.types.STRING}];
_typeServerRpcRequest.kind = vdl.kind.STRUCT;
_typeServerRpcRequest.name = "v.io/x/ref/services/wspr/internal/rpc/server.ServerRpcRequest";
_typeServerRpcRequest.fields = [{name: "ServerId", type: vdl.types.UINT32}, {name: "Handle", type: vdl.types.INT32}, {name: "Method", type: vdl.types.STRING}, {name: "Args", type: _type1}, {name: "Call", type: _typeServerRpcRequestCall}];
_typeServerRpcRequestCall.kind = vdl.kind.STRUCT;
_typeServerRpcRequestCall.name = "v.io/x/ref/services/wspr/internal/rpc/server.ServerRpcRequestCall";
-_typeServerRpcRequestCall.fields = [{name: "SecurityCall", type: _typeSecurityCall}, {name: "Deadline", type: new time.WireDeadline()._type}, {name: "Context", type: _typeContext}, {name: "TraceRequest", type: new vtrace.Request()._type}, {name: "GrantedBlessings", type: new principal.BlessingsId()._type}];
+_typeServerRpcRequestCall.fields = [{name: "SecurityCall", type: _typeSecurityCall}, {name: "Deadline", type: new time.WireDeadline()._type}, {name: "Context", type: _typeContext}, {name: "TraceRequest", type: new vtrace.Request()._type}, {name: "GrantedBlessings", type: _type6}];
_type1.freeze();
_type2.freeze();
_type3.freeze();
_type4.freeze();
_type5.freeze();
_type6.freeze();
+_type7.freeze();
_typeAuthReply.freeze();
_typeCaveatValidationRequest.freeze();
_typeCaveatValidationResponse.freeze();
diff --git a/src/proxy/message-type.js b/src/proxy/message-type.js
index 769ae7d..04600e1 100644
--- a/src/proxy/message-type.js
+++ b/src/proxy/message-type.js
@@ -30,7 +30,6 @@
CANCEL: 7, // A request to cancel a previously invoked JS method.
CAVEAT_VALIDATION_REQUEST: 8, // A request to validate a set of caveats
LOG_MESSAGE: 9, // A request to log a message.
- GRANTER_REQUEST: 10, // A request to call a granter
- BLESSINGS_CACHE_MESSAGE: 11, // A request to update the blessings cache
+ GRANTER_REQUEST: 10 // A request to call a granter
}
};
diff --git a/src/proxy/stream-handler.js b/src/proxy/stream-handler.js
index b0df421..79b2332 100644
--- a/src/proxy/stream-handler.js
+++ b/src/proxy/stream-handler.js
@@ -6,9 +6,9 @@
var emitStreamError = require('../lib/emit-stream-error');
var vError = require('../gen-vdl/v.io/v23/verror');
var SharedContextKeys = require('../runtime/shared-context-keys');
-var BlessingsId =
- require('../gen-vdl/v.io/x/ref/services/wspr/internal/principal').BlessingsId;
-var runtimeFromContext = require('../runtime/runtime-from-context');
+var Blessings = require('../security/blessings');
+var JsBlessings =
+ require('../gen-vdl/v.io/x/ref/services/wspr/internal/principal').JsBlessings;
var TaskSequence = require('../lib/task-sequence');
var Promise = require('../lib/promise');
var vom = require('../vom');
@@ -58,16 +58,12 @@
}
var handler = this;
return vom.decode(data).then(function(data) {
- if (data instanceof BlessingsId) {
- var runtime = runtimeFromContext(handler._ctx);
- runtime.blessingsManager.blessingsFromId(data)
- .then(function(blessings) {
- blessings.retain();
- handler._stream._queueRead(blessings);
- });
- } else {
- handler._stream._queueRead(data);
+ if (data instanceof JsBlessings) {
+ data = new Blessings(data.handle, data.publicKey,
+ handler._controller);
+ data.retain();
}
+ handler._stream._queueRead(data);
}, function(e) {
emitStreamError(handler._stream,
new vError.InternalError(
diff --git a/src/rpc/client.js b/src/rpc/client.js
index 6246266..00975e0 100644
--- a/src/rpc/client.js
+++ b/src/rpc/client.js
@@ -39,14 +39,13 @@
var SharedContextKeys = require('../runtime/shared-context-keys');
var vtrace = require('../vtrace');
var Blessings = require('../security/blessings');
-var BlessingsId =
- require('../gen-vdl/v.io/x/ref/services/wspr/internal/principal').BlessingsId;
-var ByteStreamMessageReader = require('../vom/byte-stream-message-reader');
+var JsBlessings =
+ require('../gen-vdl/v.io/x/ref/services/wspr/internal/principal').JsBlessings;
var ByteStreamMessageWriter = require('../vom/byte-stream-message-writer');
+var ByteStreamMessageReader = require('../vom/byte-stream-message-reader');
var Encoder = require('../vom/encoder');
var Decoder = require('../vom/decoder');
var TaskSequence = require('../lib/task-sequence');
-var runtimeFromContext = require('../runtime/runtime-from-context');
var vom = require('../vom');
var OutstandingRPC = function(ctx, options, cb) {
@@ -71,34 +70,37 @@
};
// Helper function to convert an out argument to the given type.
-function convertOutArg(ctx, arg, type, controller) {
- if (arg instanceof BlessingsId) {
- var runtime = runtimeFromContext(ctx);
- return runtime.blessingsManager.blessingsFromId(arg)
- .then(function(blessings) {
- if (blessings) {
- blessings.retain();
- }
- return blessings;
- });
+function convertOutArg(arg, type, controller) {
+ var canonOutArg = arg;
+ var unwrappedArg = unwrap(arg);
+ if (unwrappedArg instanceof JsBlessings) {
+ var res =
+ new Blessings(unwrappedArg.handle, unwrappedArg.publicKey, controller);
+ res.retain();
+ return res;
}
// There's no protection against bad out args if it's a JSValue.
// Otherwise, convert to the out arg type to ensure type correctness.
if (!type.equals(vdl.types.JSVALUE)) {
- try {
- return Promise.resolve(unwrap(vdl.canonicalize.reduce(arg, type)));
- } catch(err) {
- return Promise.reject(err);
- }
+ canonOutArg = vdl.canonicalize.reduce(arg, type);
}
- return Promise.resolve(unwrap(arg));
+ return unwrap(canonOutArg);
+}
+
+// Helper function to safely convert an out argument.
+// The returned error, if any is useful for a callback.
+function convertOutArgSafe(arg, type, controller) {
+ try {
+ return [undefined, convertOutArg(arg, type, controller)];
+ } catch(err) {
+ return [err, undefined];
+ }
}
OutstandingRPC.prototype.start = function() {
this._id = this._proxy.nextId();
- var ctx = this._ctx;
var self = this;
var cb;
@@ -111,25 +113,25 @@
cb = function convertToMultiArgs(err, results) { // jshint ignore:line
// If called from a deferred, the results are undefined.
- if (err) {
- origCb(err);
- return;
- }
-
// Each out argument should also be unwrapped. (results was []any)
- results = results || [];
- var resultPromises = results.map(function(res, i) {
- return convertOutArg(ctx, res, outArgTypes[i], self._controller);
- });
- Promise.all(resultPromises)
- .then(function(results) {
- results.unshift(null);
- origCb.apply(null, results);
- }).catch(origCb);
+ results = results ? results.map(function(res, i) {
+ var errOrArg = convertOutArgSafe(res, outArgTypes[i], self._controller);
+ if (errOrArg[0] && !err) {
+ err = errOrArg[0];
+ }
+ return errOrArg[1];
+ }) : [];
+
+ // TODO(alexfandrianto): Callbacks seem to be able to get both error and
+ // results, but I think we want to limit it to one or the other.
+ var resultsCopy = results.slice();
+ resultsCopy.unshift(err);
+ origCb.apply(null, resultsCopy);
};
}
var def = new Deferred(cb);
+ var ctx = this._ctx;
if (!this._cb) {
// If we are using a promise, strip single args out of the arg array.
@@ -140,29 +142,26 @@
'Internal error: incorrectly formatted out args in client');
}
-
// Each out argument should also be unwrapped. (args was []any)
- var unwrappedArgPromises = args.map(function(outArg, i) {
- return convertOutArg(ctx, outArg, outArgTypes[i], self._controller);
+ var unwrappedArgs = args.map(function(outArg, i) {
+ return convertOutArg(outArg, outArgTypes[i], self._controller);
});
- return Promise.all(unwrappedArgPromises).then(function(unwrappedArgs) {
- // We expect:
- // 0 args - return; // NOT return [];
- // 1 args - return a; // NOT return [a];
- // 2 args - return [a, b] ;
- //
- // Convert the results from array style to the expected return style.
- // undefined, a, [a, b], [a, b, c] etc
- switch(unwrappedArgs.length) {
- case 0:
- return undefined;
- case 1:
- return unwrappedArgs[0];
- default:
- return unwrappedArgs;
- }
- });
+ // We expect:
+ // 0 args - return; // NOT return [];
+ // 1 args - return a; // NOT return [a];
+ // 2 args - return [a, b] ;
+ //
+ // Convert the results from array style to the expected return style.
+ // undefined, a, [a, b], [a, b, c] etc
+ switch(unwrappedArgs.length) {
+ case 0:
+ return undefined;
+ case 1:
+ return unwrappedArgs[0];
+ default:
+ return unwrappedArgs;
+ }
});
}
diff --git a/src/rpc/create-server-call.js b/src/rpc/create-server-call.js
deleted file mode 100644
index 616f787..0000000
--- a/src/rpc/create-server-call.js
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2015 The Vanadium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-var createSecurityCall = require('../security/create-security-call');
-
-module.exports = createServerCall;
-
-/**
- * Create a server call object. This exists so that we can resolve blessings
- * before the user is given the object.
- * @private
- */
-function createServerCall(request, blessingsManager) {
- var serverCall = new ServerCall();
- if (request instanceof ServerCall) {
- serverCall.securityCall = request.securityCall.clone();
- serverCall.grantedBlessings = request.grantedBlessings;
- return Promise.resolve(serverCall);
- } else {
- var promises = [];
- promises.push(createSecurityCall(request.call.securityCall,
- blessingsManager).then(function(securityCall) {
- serverCall.securityCall = securityCall;
- }));
- if (request.call.grantedBlessings) {
- promises.push(
- blessingsManager.blessingsFromId(request.call.grantedBlessings)
- .then(function(grantedBlessings) {
- serverCall.grantedBlessings = grantedBlessings;
- })
- );
- }
- return Promise.all(promises).then(function() {
- return serverCall;
- });
- }
-}
-
-/**
- * @summary
- * A ServerCall is a context.Context subclass that includes additional
- * information about an ongoing server call.
- * @description
- * <p>Private Constructor, an instance of ServerCall is passed to every service
- * method as the first argument.</p>
- * @inner
- * @constructor
- *
- * @property {module:vanadium.security~SecurityCall} securityCall The
- * Security Call for the request.
- *
- * @property {module:vanadium.security~Blessings} grantedBlessings The
- * blessings optionally granted to the server from the client through a
- * granter.
- *
- * @property {*} methodTags The tags attached to the method,
- * interface specification in VDL.
- *
- * @memberof module:vanadium.rpc
- */
-function ServerCall() {
-}
diff --git a/src/rpc/granter-router.js b/src/rpc/granter-router.js
index 075d46c..dee6e7a 100644
--- a/src/rpc/granter-router.js
+++ b/src/rpc/granter-router.js
@@ -12,7 +12,7 @@
var MessageType = require('../proxy/message-type');
var Incoming = MessageType.Incoming;
var Outgoing = MessageType.Outgoing;
-var createSecurityCall = require('../security/create-security-call');
+var SecurityCall = require('../security/call');
var InspectableFunction = require('../lib/inspectable-function');
var GranterResponse =
require('../gen-vdl/v.io/x/ref/services/wspr/internal/app').GranterResponse;
@@ -25,14 +25,13 @@
* grant requests.
* @private
*/
-function GranterRouter(proxy, rootCtx, blessingsManager) {
+function GranterRouter(proxy, rootCtx) {
proxy.addIncomingHandler(Incoming.GRANTER_REQUEST, this);
this._proxy = proxy;
this._rootCtx = rootCtx;
this.nextGranterId = 0;
this.activeGranters = {};
- this._blessingsManager = blessingsManager;
}
/**
@@ -55,10 +54,9 @@
}
var router = this;
- var granter;
return vom.decode(request).then(function(request) {
request = request.val;
- granter = router.activeGranters[request.granterHandle];
+ var granter = router.activeGranters[request.granterHandle];
if (!granter) {
// TODO(bjornick): Pass in context here so we can generate useful error
// messages
@@ -66,11 +64,7 @@
new verror.NoExistError(router._rootCtx, 'unknown granter'));
}
delete router.activeGranters[request.granterHandle];
- return createSecurityCall(request.call, router._blessingsManager);
- }, function(e) {
- return Promise.reject(
- new verror.NoExistError(router._rootCtx, 'failed to decode message'));
- }).then(function(securityCall) {
+ var securityCall = new SecurityCall(request.call, router._controller);
var ctx = router._rootCtx;
var inspectFn = new InspectableFunction(granter);
var resolve;
@@ -87,6 +81,9 @@
return resolve(res);
});
return promise;
+ }, function(e) {
+ return Promise.reject(
+ new verror.NoExistError(router._rootCtx, 'failed to decode message'));
}).then(function(outBlessings) {
var result = new GranterResponse({blessings: outBlessings[0]._id});
var data = hexVom.encode(result);
diff --git a/src/rpc/server-call.js b/src/rpc/server-call.js
new file mode 100644
index 0000000..ae9401e
--- /dev/null
+++ b/src/rpc/server-call.js
@@ -0,0 +1,46 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+var SecurityCall = require('../security/call');
+var Blessings = require('../security/blessings');
+
+module.exports = ServerCall;
+
+/**
+ * @summary
+ * A ServerCall is a context.Context subclass that includes additional
+ * information about an ongoing server call.
+ * @description
+ * <p>Private Constructor, an instance of ServerCall is passed to every service
+ * method as the first argument.</p>
+ * @inner
+ * @constructor
+ *
+ * @property {module:vanadium.security~SecurityCall} securityCall The
+ * Security Call for the request.
+ *
+ * @property {*} methodTags The tags attached to the method,
+ * interface specification in VDL.
+ *
+ * @memberof module:vanadium.rpc
+ */
+function ServerCall(request, controller) {
+ if (!(this instanceof ServerCall)) {
+ return new ServerCall(request, controller);
+ }
+
+ if (request instanceof ServerCall) {
+ this.securityCall = request.securityCall.clone();
+ this.grantedBlessings = request.grantedBlessings;
+ } else {
+ this.securityCall = new SecurityCall(request.call.securityCall,
+ controller);
+ if (request.call.grantedBlessings) {
+ this.grantedBlessings = new Blessings(
+ request.call.grantedBlessings.handle,
+ request.call.grantedBlessings.publicKey,
+ controller);
+ }
+ }
+}
diff --git a/src/rpc/server-router.js b/src/rpc/server-router.js
index 6c4155c..82ac8c4 100644
--- a/src/rpc/server-router.js
+++ b/src/rpc/server-router.js
@@ -16,8 +16,8 @@
var vlog = require('./../lib/vlog');
var StreamHandler = require('../proxy/stream-handler');
var verror = require('../gen-vdl/v.io/v23/verror');
-var createSecurityCall = require('../security/create-security-call');
-var createServerCall = require('./create-server-call');
+var SecurityCall = require('../security/call');
+var ServerCall = require('./server-call');
var vdl = require('../vdl');
var typeUtil = require('../vdl/type-util');
var Deferred = require('../lib/deferred');
@@ -37,8 +37,8 @@
var lib =
require('../gen-vdl/v.io/x/ref/services/wspr/internal/lib');
var Blessings = require('../security/blessings');
-var BlessingsId =
- require('../gen-vdl/v.io/x/ref/services/wspr/internal/principal').BlessingsId;
+var JsBlessings =
+ require('../gen-vdl/v.io/x/ref/services/wspr/internal/principal').JsBlessings;
var WireBlessings =
require('../gen-vdl/v.io/v23/security').WireBlessings;
var SharedContextKeys = require('../runtime/shared-context-keys');
@@ -52,8 +52,7 @@
* @constructor
* @private
*/
-var Router = function(
- proxy, appName, rootCtx, controller, caveatRegistry, blessingsManager) {
+var Router = function(proxy, appName, rootCtx, controller, caveatRegistry) {
this._servers = {};
this._proxy = proxy;
this._streamMap = {};
@@ -63,7 +62,6 @@
this._caveatRegistry = caveatRegistry;
this._outstandingRequestForId = {};
this._controller = controller;
- this._blessingsManager = blessingsManager;
proxy.addIncomingHandler(Incoming.INVOKE_REQUEST, this);
proxy.addIncomingHandler(Incoming.LOOKUP_REQUEST, this);
@@ -119,15 +117,11 @@
}
var router = this;
- var decodedRequest;
- vom.decode(request).catch(function(e) {
- return Promise.reject(new verror.InternalError(router._rootCtx,
- 'Failed to decode ', e));
- }).then(function(req) {
- decodedRequest = req;
+ var call;
+ vom.decode(request).then(function(request) {
var ctx = router._rootCtx.withValue(SharedContextKeys.LANG_KEY,
- decodedRequest.context.language);
- var server = router._servers[decodedRequest.serverId];
+ request.context.language);
+ var server = router._servers[request.serverId];
if (!server) {
var authReply = new AuthReply({
// TODO(bjornick): Use the real context
@@ -138,20 +132,22 @@
null, messageId);
return;
}
- return createSecurityCall(decodedRequest.call, router._blessingsManager)
- .then(function(call) {
- return server.handleAuthorization(decodedRequest.handle, ctx, call);
- });
+ call = new SecurityCall(request.call, router._controller);
+
+ return server.handleAuthorization(request.handle, ctx, call);
+ }, function(e) {
+ return Promise.reject(new verror.InternalError(router._rootCtx,
+ 'Failed to decode ', e));
}).then(function() {
var authReply = new AuthReply({});
router._proxy.sendRequest(hexVom.encode(authReply),
Outgoing.AUTHORIZATION_RESPONSE, null, messageId);
}).catch(function(e) {
- var errMsg = {
- err: ErrorConversion.fromNativeValue(e, this._appName,
- decodedRequest.call.method)
- };
- router._proxy.sendRequest(hexVom.encode(errMsg),
+ var authReply = new AuthReply({
+ err: ErrorConversion.fromNativeValue(e, router._appName,
+ call.method)
+ });
+ router._proxy.sendRequest(hexVom.encode(authReply),
Outgoing.AUTHORIZATION_RESPONSE, null,
messageId);
});
@@ -183,24 +179,24 @@
};
Router.prototype.handleCaveatValidationRequest = function(messageId, request) {
- var router = this;
- createSecurityCall(request.call, this._blessingsManager)
- .then(function(call) {
- var ctx = router._rootCtx.withValue(SharedContextKeys.LANG_KEY,
- request.context.language);
- var resultPromises = request.cavs.map(function(cav) {
- return router._validateChain(ctx, call, cav);
+ var resultPromises = new Array(request.cavs.length);
+ var call = new SecurityCall(request.call);
+ var ctx = this._rootCtx.withValue(SharedContextKeys.LANG_KEY,
+ request.context.language);
+ for (var i = 0; i < request.cavs.length; i++) {
+ resultPromises[i] = this._validateChain(ctx, call, request.cavs[i]);
+ }
+ var self = this;
+ Promise.all(resultPromises).then(function(results) {
+ var response = new CaveatValidationResponse({
+ results: results
});
- return Promise.all(resultPromises).then(function(results) {
- var response = new CaveatValidationResponse({
- results: results
- });
- var data = hexVom.encode(response);
- router._proxy.sendRequest(data, Outgoing.CAVEAT_VALIDATION_RESPONSE, null,
- messageId);
- });
+ self._proxy.sendRequest(hexVom.encode(response),
+ Outgoing.CAVEAT_VALIDATION_RESPONSE, null,
+ messageId);
}).catch(function(err) {
- throw new Error('Unexpected error (all promises should resolve): ' + err);
+ vlog.logger.error(
+ new Error('Unexpected error (all promises should resolve): ' + err));
});
};
@@ -219,24 +215,24 @@
var self = this;
return server._handleLookup(request.suffix).then(function(value) {
- var signatureList = value.invoker.signature();
- var hasAuthorizer = (typeof value.authorizer === 'function');
- var hasGlobber = value.invoker.hasGlobber();
- var reply = new LookupReply({
- handle: value._handle,
- signature: signatureList,
- hasAuthorizer: hasAuthorizer,
- hasGlobber: hasGlobber
- });
- self._proxy.sendRequest(hexVom.encode(reply), Outgoing.LOOKUP_RESPONSE,
- null, messageId);
- }).catch(function(err) {
- var reply = new LookupReply({
- err: ErrorConversion.fromNativeValue(err, self._appName, '__Signature')
- });
- self._proxy.sendRequest(hexVom.encode(reply), Outgoing.LOOKUP_RESPONSE,
- null, messageId);
- });
+ var signatureList = value.invoker.signature();
+ var hasAuthorizer = (typeof value.authorizer === 'function');
+ var hasGlobber = value.invoker.hasGlobber();
+ var reply = new LookupReply({
+ handle: value._handle,
+ signature: signatureList,
+ hasAuthorizer: hasAuthorizer,
+ hasGlobber: hasGlobber
+ });
+ self._proxy.sendRequest(hexVom.encode(reply), Outgoing.LOOKUP_RESPONSE,
+ null, messageId);
+ }).catch(function(err) {
+ var reply = new LookupReply({
+ err: ErrorConversion.fromNativeValue(err, self._appName, '__Signature')
+ });
+ self._proxy.sendRequest(hexVom.encode(reply), Outgoing.LOOKUP_RESPONSE,
+ null, messageId);
+ });
};
/**
@@ -310,118 +306,111 @@
var ctx = this.createRPCContext(request);
var self = this;
var stream;
- createServerCall(request, this._blessingsManager).then(function(call) {
- if (request.method === 'Glob__') {
- if (!invoker.hasGlobber()) {
- err = new Error('Glob is not implemented');
- self.sendResult(messageId, 'Glob__', null, err);
- return;
- }
- // Glob takes no streaming input and has GlobReply as output.
- stream = new Stream(messageId, self._proxy.senderPromise, false,
- null, naming.GlobReply.prototype._type);
- self._streamMap[messageId] = stream;
- self._contextMap[messageId] = ctx;
- self._outstandingRequestForId[messageId] = 0;
- self.incrementOutstandingRequestForId(messageId);
- var globPattern = typeUtil.unwrap(request.args[0]);
- self.handleGlobRequest(messageId, call.securityCall.suffix,
- server, new Glob(globPattern), ctx, call, invoker,
- completion);
+ var call = new ServerCall(request, this._controller);
+ if (request.method === 'Glob__') {
+ if (!invoker.hasGlobber()) {
+ err = new Error('Glob is not implemented');
+ self.sendResult(messageId, 'Glob__', null, err);
return;
}
+ // Glob takes no streaming input and has GlobReply as output.
+ stream = new Stream(messageId, this._proxy.senderPromise, false,
+ null, naming.GlobReply.prototype._type);
+ this._streamMap[messageId] = stream;
+ this._contextMap[messageId] = ctx;
+ this._outstandingRequestForId[messageId] = 0;
+ this.incrementOutstandingRequestForId(messageId);
+ var globPattern = typeUtil.unwrap(request.args[0]);
+ this.handleGlobRequest(messageId, call.securityCall.suffix,
+ server, new Glob(globPattern), ctx, call, invoker,
+ completion);
+ return;
+ }
- function completion() {
- // There is no results to a glob method. Everything is sent back
- // through the stream.
- self.sendResult(messageId, methodName, null, undefined, 1);
- }
+ function completion() {
+ // There is no results to a glob method. Everything is sent back
+ // through the stream.
+ self.sendResult(messageId, methodName, null, undefined, 1);
+ }
- // Find the method signature.
- var signature = invoker.signature();
- var methodSig;
- signature.forEach(function(ifaceSig) {
- ifaceSig.methods.forEach(function(method) {
- if (method.name === methodName) {
- methodSig = method;
- }
- });
- });
- if (methodSig === undefined) {
- err = new verror.NoExistError(
- call, 'Requested method', methodName, 'not found on');
- self.sendResult(messageId, methodName, null, err);
- return;
- }
-
- // Unwrap the RPC arguments sent to the JS server.
- var unwrappedArgPromises = request.args.map(function(arg, i) {
- // If an any type was expected, unwrapping is not needed.
- if (methodSig.inArgs[i].type.kind === vdl.kind.ANY) {
- return Promise.resolve(arg);
+ // Find the method signature.
+ var signature = invoker.signature();
+ var methodSig;
+ signature.forEach(function(ifaceSig) {
+ ifaceSig.methods.forEach(function(method) {
+ if (method.name === methodName) {
+ methodSig = method;
}
- var unwrapped = typeUtil.unwrap(arg);
- if (unwrapped instanceof BlessingsId) {
- return self._blessingsManager.blessingsFromId(unwrapped);
- }
- return Promise.resolve(unwrapped);
- });
-
- return Promise.all(unwrappedArgPromises).then(function(unwrappedArgs) {
- var options = {
- methodName: methodName,
- args: unwrappedArgs,
- methodSig: methodSig,
- ctx: ctx,
- call: call,
- };
-
- self._contextMap[messageId] = options.ctx;
- if (methodIsStreaming(methodSig)) {
- var readType = (methodSig.inStream ? methodSig.inStream.type : null);
- var writeType = (methodSig.outStream ? methodSig.outStream.type : null);
- stream = new Stream(messageId, self._proxy.senderPromise, false,
- readType, writeType);
- self._streamMap[messageId] = stream;
- var rpc = new StreamHandler(options.ctx, stream);
- self._proxy.addIncomingStreamHandler(messageId, rpc);
- options.stream = stream;
- }
-
- // Invoke the method;
- self.invokeMethod(invoker, options, function(err, results) {
- if (err) {
- var stackTrace;
- if (err instanceof Error && err.stack !== undefined) {
- stackTrace = err.stack;
- }
- vlog.logger.debug('Requested method ' + methodName +
- ' threw an exception on invoke: ', err, stackTrace);
-
- // The error case has no results; only send the error.
- self.sendResult(messageId, methodName, undefined, err,
- methodSig.outArgs.length);
- return;
- }
-
- // Has results; associate the types of the outArgs.
- var canonResults = results.map(function(result, i) {
- var t = methodSig.outArgs[i].type;
- if (t.equals(WireBlessings.prototype._type)) {
- if (!(result instanceof Blessings)) {
- vlog.logger.error(
- 'Encoding non-blessings value as wire blessings');
- return null;
- }
- return result;
- }
- return vdl.canonicalize.fill(result, t);
- });
- self.sendResult(messageId, methodName, canonResults, undefined,
- methodSig.outArgs.length);
- });
});
});
+ if (methodSig === undefined) {
+ err = new verror.NoExistError(
+ call, 'Requested method', methodName, 'not found on');
+ this.sendResult(messageId, methodName, null, err);
+ return;
+ }
+
+ // Unwrap the RPC arguments sent to the JS server.
+ var unwrappedArgs = request.args.map(function(arg, i) {
+ // If an any type was expected, unwrapping is not needed.
+ if (methodSig.inArgs[i].type.kind === vdl.kind.ANY) {
+ return arg;
+ }
+ var unwrapped = typeUtil.unwrap(arg);
+ if (unwrapped instanceof JsBlessings) {
+ return new Blessings(unwrapped.handle, unwrapped.publicKey,
+ self._controller);
+ }
+ return unwrapped;
+ });
+ var options = {
+ methodName: methodName,
+ args: unwrappedArgs,
+ methodSig: methodSig,
+ ctx: ctx,
+ call: call,
+ };
+
+ this._contextMap[messageId] = options.ctx;
+ if (methodIsStreaming(methodSig)) {
+ var readType = (methodSig.inStream ? methodSig.inStream.type : null);
+ var writeType = (methodSig.outStream ? methodSig.outStream.type : null);
+ stream = new Stream(messageId, this._proxy.senderPromise, false, readType,
+ writeType);
+ this._streamMap[messageId] = stream;
+ var rpc = new StreamHandler(options.ctx, stream);
+ this._proxy.addIncomingStreamHandler(messageId, rpc);
+ options.stream = stream;
+ }
+
+ // Invoke the method;
+ this.invokeMethod(invoker, options, function(err, results) {
+ if (err) {
+ var stackTrace;
+ if (err instanceof Error && err.stack !== undefined) {
+ stackTrace = err.stack;
+ }
+ vlog.logger.debug('Requested method ' + methodName +
+ ' threw an exception on invoke: ', err, stackTrace);
+
+ // The error case has no results; only send the error.
+ self.sendResult(messageId, methodName, undefined, err,
+ methodSig.outArgs.length);
+ return;
+ }
+
+ // Has results; associate the types of the outArgs.
+ var canonResults = results.map(function(result, i) {
+ var t = methodSig.outArgs[i].type;
+ if (t.equals(WireBlessings.prototype._type)) {
+ return result;
+ }
+ return vdl.canonicalize.fill(result, t);
+ });
+ self.sendResult(messageId, methodName, canonResults, undefined,
+ methodSig.outArgs.length);
+ });
+
};
/**
* Handles incoming requests from the server to invoke methods on registered
@@ -561,13 +550,10 @@
var suffix = namespaceUtil.join(name, child);
self.incrementOutstandingRequestForId(messageId);
+ var subCall = new ServerCall(call);
+ subCall.securityCall.suffix = suffix;
var nextInvoker;
- var subCall;
- createServerCall(call, this._blessingsManager).then(function(servCall) {
- subCall = servCall;
- subCall.securityCall.suffix = suffix;
- return server._handleLookup(suffix);
- }).then(function(value) {
+ server._handleLookup(suffix).then(function(value) {
nextInvoker = value.invoker;
return server.handleAuthorization(value._handle, context,
subCall.securityCall);
diff --git a/src/runtime/index.js b/src/runtime/index.js
index 7c51044..8f4a379 100644
--- a/src/runtime/index.js
+++ b/src/runtime/index.js
@@ -23,8 +23,6 @@
var vtrace = require('../vtrace');
var Controller =
require('../gen-vdl/v.io/x/ref/services/wspr/internal/app').Controller;
-var BlessingsManager = require('../security/blessings-manager');
-var BlessingsRouter = require('../security/blessings-router');
module.exports = {
init: init
@@ -119,9 +117,6 @@
this._name = options.appName;
this._language = options.language;
this.caveatRegistry = new CaveatValidatorRegistry();
- this.blessingsManager = new BlessingsManager(this._controller);
- this._blessingsRouter = new BlessingsRouter(this._getProxyConnection(),
- this.blessingsManager);
}
inherits(Runtime, EE);
@@ -254,8 +249,7 @@
this._name,
this.getContext(),
this._controller,
- this.caveatRegistry,
- this.blessingsManager);
+ this.caveatRegistry);
}
return this._router;
};
@@ -269,8 +263,7 @@
if (!this._granterRouter) {
this._granterRouter = new GranterRouter(
this._getProxyConnection(),
- this.getContext(),
- this.blessingsManager);
+ this.getContext());
}
return this._granterRouter;
};
diff --git a/src/security/access/permissions-authorizer.js b/src/security/access/permissions-authorizer.js
index 117b5db..c2a03ad 100644
--- a/src/security/access/permissions-authorizer.js
+++ b/src/security/access/permissions-authorizer.js
@@ -12,7 +12,7 @@
var NoPermissionsError = vdlAccess.NoPermissionsError;
var Permissions = vdlAccess.Permissions;
-module.exports = permissionsAuthorizer;
+module.exports = authorizer;
var pkgPath = 'v.io/v23/security/access';
var MultipleTagsError = makeError(
pkgPath + '.errMultipleMethodTags',
@@ -38,7 +38,7 @@
* @return {module:vanadium.security.Authorize} An authorizer that applies
* the perms.
*/
-function permissionsAuthorizer(perms, type) {
+function authorizer(perms, type) {
// Force the Permissions to have the correct Permissions format.
var permissions = unwrap(new Permissions(perms));
@@ -70,4 +70,4 @@
}
return;
};
-}
+}
\ No newline at end of file
diff --git a/src/security/blessings-cache.js b/src/security/blessings-cache.js
deleted file mode 100644
index e3b0444..0000000
--- a/src/security/blessings-cache.js
+++ /dev/null
@@ -1,130 +0,0 @@
-// Copyright 2015 The Vanadium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-var unwrap = require('../vdl/type-util').unwrap;
-var vlog = require('../lib/vlog');
-var Deferred = require('../lib/deferred');
-
-/**
- * @fileoverview A cache of blessings, used in conjunction with the cache
- * in WSPR (principal/cache.go) to reduce the number of times blessings must
- * be sent across the wire.
- * This is kept in sync with the WSPR cache.
- * @private
- */
-
-module.exports = BlessingsCache;
-
-/**
- * @summary Cache of blessings received from WSPR.
- * @description This cache is kept in sync with WSPR to reduce the
- * number of times that blessings must be sent across the wire.
- * @constructor
- * @private
- */
-function BlessingsCache() {
- // Each entry has the following fields (which may or may not exist):
- // - deferredBlessings: a deferred object whose promise resolves to the
- // blessings
- // - refCount: number of references to the blessings
- // - deleteAfter: delete the entry after this number of blessings
- this._entries = {};
-}
-
-/**
- * @summary addBlessings adds blessings to the blessings cache.
- * @param {wspr.internal.principal.BlessingsCacheAddMessage} addMessage
- */
-BlessingsCache.prototype.addBlessings = function(addMessage) {
- var id = this._unwrappedId(addMessage.cacheId);
- var entry = this._getOrCreateEntry(id);
- entry.deferredBlessings.resolve(addMessage.blessings);
-};
-
-/**
- * @summary deleteBlessings removes blessings from the blessings cache.
- * @param {wspr.internal.principal.BlessingsCacheAddMessage} addMessage
- */
-BlessingsCache.prototype.deleteBlessings = function(deleteMessage) {
- var id = this._unwrappedId(deleteMessage.cacheId);
- var entry = this._getOrCreateEntry(id);
- entry.deleteAfter = deleteMessage.deleteAfter;
-
- this._deleteIfNoLongerNeeded(id);
-};
-
-/**
- * @summary blessingsFromId looks up a blessing by id or waits for it if it
- * has not been put in the cache yet
- * @param {wspr.internal.principal.BlessingsId} blessingsId
- */
-BlessingsCache.prototype.blessingsFromId = function(blessingsId) {
- var id = unwrap(blessingsId);
-
- if (typeof id !== 'number') {
- throw new Error('Expected numeric blessings id');
- }
- if (id === 0) {
- // Zero is not a valid id.
- // TODO(bprosnitz) Replace this with null once we switch to full blessings
- // objects. It is currently a number because there are no optional numbers
- // now in VDL.
- return Promise.resolve(null);
- }
-
- var entry = this._getOrCreateEntry(id);
- var cache = this;
- return entry.deferredBlessings.promise.then(function(blessings) {
- cache._increaseRefCount(id);
- cache._deleteIfNoLongerNeeded(id);
- return blessings;
- });
-};
-
-BlessingsCache.prototype._increaseRefCount = function(cacheId) {
- var entry = this._entries[cacheId];
- if (!entry) {
- throw new Error('Unexpectedly got id of missing entry');
- }
- entry.refCount++;
-};
-
-BlessingsCache.prototype._deleteIfNoLongerNeeded = function(cacheId) {
- var entry = this._entries[cacheId];
- if (!entry) {
- throw new Error('Entry unexpectedly not present');
- }
-
- if (entry.refCount >= entry.deleteAfter) {
- if (entry.refCount > entry.deleteAfter) {
- vlog.logger.warn('Got more references than expected');
- }
- if (entry.waiting) {
- vlog.logger.warn(
- 'There should not be anything waiting on entry to be deleted');
- }
- delete this._entries[cacheId];
- }
-};
-
-BlessingsCache.prototype._getOrCreateEntry = function(cacheId) {
- if (!this._entries[cacheId]) {
- this._entries[cacheId] = {
- refCount: 0,
- deferredBlessings: new Deferred()
- };
- }
- return this._entries[cacheId];
-};
-
-BlessingsCache.prototype._unwrappedId = function(cacheId) {
- var id = unwrap(cacheId);
- if (typeof id !== 'number') {
- throw new Error('Got non-numeric id');
- }
- if (id <= 0) {
- throw new Error('Unexpected non-positive id ' + id);
- }
- return id;
-};
diff --git a/src/security/blessings-manager.js b/src/security/blessings-manager.js
deleted file mode 100644
index 723b1d7..0000000
--- a/src/security/blessings-manager.js
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2015 The Vanadium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-/**
- * @fileoverview Manager of cache blessings. This differs from BlessingsCache
- * because it converts JsBlessings to Blessings objects.
- * TODO(bprosnitz) Remove this after switching to performing WireBlessings to
- * Blessings conversion with native types.
- * @private
- */
-
-var BlessingsCache = require('../security/blessings-cache');
-var Blessings = require('../security/blessings');
-
-
-module.exports = BlessingsManager;
-
-/*
- * TODO(bprosnitz) Replace this with just BlessingsCache after switching
- * to using native type conversion with blessings.
- */
-/*
- * @summary Manager of blessings received from WSPR.
- * @constructor
- * @inner
- */
-function BlessingsManager(controller) {
- this._blessingsCache = new BlessingsCache();
- this._controller = controller;
-}
-
-BlessingsManager.prototype.blessingsFromId = function(id) {
- var controller = this._controller;
- return this._blessingsCache.blessingsFromId(id).then(function(jsBless) {
- if (!jsBless) {
- return null;
- }
- return new Blessings(jsBless.handle, jsBless.publicKey, controller);
- });
-};
-
-BlessingsManager.prototype.addBlessings = function(addMessage) {
- return this._blessingsCache.addBlessings(addMessage);
-};
-
-BlessingsManager.prototype.deleteBlessings = function(deleteMessage) {
- return this._blessingsCache.deleteBlessings(deleteMessage);
-};
diff --git a/src/security/blessings-router.js b/src/security/blessings-router.js
deleted file mode 100644
index 4254bf9..0000000
--- a/src/security/blessings-router.js
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2015 The Vanadium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-/**
- * @fileoveriew A router that handles incoming requests to update the state
- * of the blessings cache.
- * @private
- */
-
-var vlog = require('./../lib/vlog');
-var Incoming = require('../proxy/message-type').Incoming;
-
-module.exports = BlessingsRouter;
-
-/**
- * A router that handles incoming requests to update the state of the blessings
- * cache.
- * @constructor
- * @private
- */
-function BlessingsRouter(proxy, blessingsManager) {
- this._blessingsManager = blessingsManager;
-
- proxy.addIncomingHandler(Incoming.BLESSINGS_CACHE_MESSAGE, this);
-}
-
-BlessingsRouter.prototype.handleRequest = function(messageId, type, request) {
- switch (type) {
- case Incoming.BLESSINGS_CACHE_MESSAGE:
- this.handleBlessingsCacheMessages(request);
- return;
- default:
- vlog.logger.error('Unknown request type given to blessings router ' + type);
- }
-};
-
-BlessingsRouter.prototype.handleBlessingsCacheMessages = function(messages) {
- for (var i = 0; i < messages.length; i++) {
- var message = messages[i];
- if (message.hasOwnProperty('add')) {
- this._blessingsManager.addBlessings(message.add);
- } else if (message.hasOwnProperty('delete')) {
- this._blessingsManager.deleteBlessings(message.delete);
- } else {
- vlog.logger.error('Unknown blessings cache message: ', message);
- }
- }
-};
diff --git a/src/security/blessingstore.js b/src/security/blessingstore.js
index ec74dd6..4ce7a31 100644
--- a/src/security/blessingstore.js
+++ b/src/security/blessingstore.js
@@ -8,7 +8,7 @@
*/
var Deferred = require('../lib/deferred');
- var runtimeFromContext = require('../../src/runtime/runtime-from-context');
+ var Blessings = require('./blessings');
var verror = require('../gen-vdl/v.io/v23/verror');
module.exports = BlessingStore;
@@ -185,17 +185,14 @@
controller.blessingStorePeerBlessings(ctx)
.then(function(peerBlessings) {
var outPeerBlessings = new Map();
- var promises = [];
- peerBlessings.forEach(function(blessId, pattern) {
- var runtime = runtimeFromContext(ctx);
- promises.push(runtime.blessingsManager.blessingsFromId(blessId)
- .then(function(blessingsObj) {
- outPeerBlessings.set(pattern, blessingsObj);
- }));
+ peerBlessings.forEach(function(jsBlessings, pattern) {
+ var blessingObj = new Blessings(
+ jsBlessings.handle,
+ jsBlessings.publicKey,
+ controller);
+ outPeerBlessings.set(pattern, blessingObj);
});
- return Promise.all(promises).then(function() {
- def.resolve(outPeerBlessings);
- });
+ def.resolve(outPeerBlessings);
}).catch(function(err) {
def.reject(err);
});
diff --git a/src/security/call.js b/src/security/call.js
new file mode 100644
index 0000000..daf095f
--- /dev/null
+++ b/src/security/call.js
@@ -0,0 +1,63 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/**
+ * @fileoverview A context passed to the authorizer
+ * @private
+ */
+var Blessings = require('./blessings.js');
+module.exports = Call;
+
+/**
+ * @summary Call defines the state available for authorizing a principal.
+ * @name SecurityCall
+ * @property {string} method The method being invoked.
+ * @property {string} suffix The object name suffix of the request.
+ * @property {module:vanadium.security~Blessings} localBlessings The blessings
+ * bound to the local end.
+ * @property {string} localBlessingStrings The validated names for the local
+ * end.
+ * @property {module:vanadium.security~Blessings} remoteBlessings The blessings
+ * bound to the remote end.
+ * @property {string} remoteBlessingStrings The validated names for the remote
+ * end.
+ * @property {string} localEndpoint The endpoint string for the local end.
+ * @property {string} remoteEndpoint The endpoint string for the remote end.
+ * @inner
+ * @memberof module:vanadium.security
+ */
+function Call(call, controller) {
+ this.method = call.method;
+ this.suffix = call.suffix;
+ // TODO(bjornick): Use the enums.
+ this.methodTags = call.methodTags;
+ this.localBlessings = new Blessings(call.localBlessings.handle,
+ call.localBlessings.publicKey,
+ controller);
+ this.remoteBlessings = new Blessings(call.remoteBlessings.handle,
+ call.remoteBlessings.publicKey,
+ controller);
+ if (call.grantedBlessings) {
+ this.grantedBlessings = new Blessings(call.grantedBlessings.handle,
+ call.grantedBlessings.publicKey,
+ controller);
+ }
+ this.localBlessingStrings = call.localBlessingStrings;
+ this.remoteBlessingStrings = call.remoteBlessingStrings;
+ // TODO(bjornick): Create endpoints.
+ this.localEndpoint = call.localEndpoint;
+ this.remoteEndpoint = call.remoteEndpoint;
+}
+
+Call.prototype.clone = function() {
+ var res = Object.create(this.constructor.prototype);
+ Object.defineProperty(res, 'constructor', { value: this.constructor });
+ for (var key in this) {
+ if (!this.hasOwnProperty(key)) {
+ continue;
+ }
+ res[key] = this[key];
+ }
+ return res;
+};
diff --git a/src/security/create-security-call.js b/src/security/create-security-call.js
deleted file mode 100644
index 8cdd467..0000000
--- a/src/security/create-security-call.js
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2015 The Vanadium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-/**
- * @fileoverview A security information passes to authorizer and validator.
- * @private
- */
-module.exports = createSecurityCall;
-
-/**
- * Create a security call object. This exists so that we can resolve blessings
- * before the user is given the object.
- * @private
- */
-function createSecurityCall(input, blessingsManager) {
- var call = new Call();
- call.method = input.method;
- call.suffix = input.suffix;
- call.methodTags = input.methodTags;
- call.localBlessingStrings = input.localBlessingStrings;
- call.remoteBlessingStrings = input.remoteBlessingStrings;
- // TODO(bjornick): Create endpoints.
- call.localEndpoint = input.localEndpoint;
- call.remoteEndpoint = input.remoteEndpoint;
-
- var promises = [];
- promises.push(blessingsManager.blessingsFromId(input.localBlessings)
- .then(function(localBlessings) {
- call.localBlessings = localBlessings;
- }));
- promises.push(blessingsManager.blessingsFromId(input.remoteBlessings)
- .then(function(remoteBlessings) {
- call.remoteBlessings = remoteBlessings;
- return call;
- }));
-
- return Promise.all(promises).then(function() {
- return call;
- });
-}
-
-/**
- * @summary Call defines the state available for authorizing a principal.
- * @name SecurityCall
- * @property {string} method The method being invoked.
- * @property {string} suffix The object name suffix of the request.
- * @property {module:vanadium.security~Blessings} localBlessings The blessings
- * bound to the local end.
- * @property {string} localBlessingStrings The validated names for the local
- * end.
- * @property {module:vanadium.security~Blessings} remoteBlessings The blessings
- * bound to the remote end.
- * @property {string} remoteBlessingStrings The validated names for the remote
- * end.
- * @property {string} localEndpoint The endpoint string for the local end.
- * @property {string} remoteEndpoint The endpoint string for the remote end.
- * @inner
- * @memberof module:vanadium.security
- */
-function Call() {
-}
-
-Call.prototype.clone = function() {
- var res = Object.create(this.constructor.prototype);
- Object.defineProperty(res, 'constructor', { value: this.constructor });
- for (var key in this) {
- if (!this.hasOwnProperty(key)) {
- continue;
- }
- res[key] = this[key];
- }
- return res;
-};
diff --git a/src/security/default-authorizer.js b/src/security/default-authorizer.js
index 6a952b4..a16958f 100644
--- a/src/security/default-authorizer.js
+++ b/src/security/default-authorizer.js
@@ -5,9 +5,9 @@
var blessingMatches = require('./access/blessing-matching');
var vError = require('./../gen-vdl/v.io/v23/verror');
-module.exports = defaultAuthorizer;
+module.exports = authorizer;
-function defaultAuthorizer(ctx, call, cb) {
+function authorizer(ctx, call, cb) {
// If the remoteBlessings has a public key, and it refers to ourselves
// (i.e a self rpc), then we always authorize.
if (call.remoteBlessings.publicKey &&
diff --git a/src/security/principal.js b/src/security/principal.js
index afc40cc..bd69964 100644
--- a/src/security/principal.js
+++ b/src/security/principal.js
@@ -8,6 +8,7 @@
*/
var Deferred = require('../lib/deferred');
+var Blessings = require('./blessings');
var BlessingStore = require('./blessingstore');
var verror = require('../gen-vdl/v.io/v23/verror');
@@ -80,9 +81,12 @@
var caveats = args.slice(4);
+ var controller = this._controller;
this._controller.bless(ctx, publicKey, blessings._id, extension, caveats)
- .then(function(blessings) {
- def.resolve(blessings);
+ .then(function(res) {
+ var publicKey = res[0];
+ var handle = res[1];
+ def.resolve(new Blessings(handle, publicKey, controller));
}).catch(function(err) {
def.reject(err);
});
@@ -117,11 +121,14 @@
var controller = this._controller;
controller.blessSelf(ctx, name, caveats)
- .then(function(blessings) {
- def.resolve(blessings);
+ .then(function(res) {
+ var publicKey = res[0];
+ var handle = res[1];
+ def.resolve(new Blessings(handle, publicKey, controller));
}).catch(function(err) {
def.reject(err);
});
+
return def.promise;
};
diff --git a/test/integration/test-authorizer.js b/test/integration/test-authorizer.js
index b8ff575..895ead4 100644
--- a/test/integration/test-authorizer.js
+++ b/test/integration/test-authorizer.js
@@ -56,9 +56,10 @@
var ctx = res.runtime.getContext();
client.bindTo(ctx, 'authorizerTestService/auth').then(function(service) {
service.call(ctx, 'foo').then(function(value) {
- assert.error(new Error('call should not have succeeded. res:' + value));
+ assert.error(new Error('call should not have succeeded' + value));
res.end(assert);
}).catch(function(err) {
+ // We expect to get to the error case.
assert.ok(err);
res.end(assert);
});
diff --git a/test/unit/test-blessings-cache.js b/test/unit/test-blessings-cache.js
deleted file mode 100644
index 1999e3c..0000000
--- a/test/unit/test-blessings-cache.js
+++ /dev/null
@@ -1,337 +0,0 @@
-// Copyright 2015 The Vanadium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-var test = require('prova');
-var BlessingsCache = require('../../src/security/blessings-cache');
-var principal =
- require('../../src/gen-vdl/v.io/x/ref/services/wspr/internal/principal');
-
-test('Blessing cache - add before use', function(t) {
- var blessingsA = {
- publicKey: 'A'
- };
- var messages = [
- {
- type: 'add',
- value: {
- cacheId: 1,
- blessings: blessingsA
- }
- },
- {
- type: 'blessingsFromId',
- cacheId: 1,
- expected: blessingsA
- }
- ];
-
- testCache(t, messages);
-});
-
-test('Blessing cache - add after use', function(t) {
- var blessingsA = {
- publicKey: 'A'
- };
- var messages = [
- {
- type: 'blessingsFromId',
- cacheId: 1,
- expected: blessingsA
- },
- {
- type: 'add',
- value: {
- cacheId: 1,
- blessings: blessingsA
- },
- dontWaitPrevious: true
- }
- ];
-
- testCache(t, messages);
-});
-
-test('Blessing cache - delete after add', function(t) {
- var blessingsA = {
- publicKey: 'A'
- };
- var messages = [
- {
- type: 'add',
- value: {
- cacheId: 1,
- blessings: blessingsA
- }
- },
- {
- type: 'delete',
- value: {
- cacheId: 1,
- deleteAfter: 0
- },
- },
- {
- type: 'confirmDelete',
- cacheId: 1
- }
- ];
-
- testCache(t, messages);
-});
-
-test('Blessing cache - reference counting delete', function(t) {
- var blessingsA = {
- publicKey: 'A'
- };
- var messages = [
- {
- type: 'add',
- value: {
- cacheId: 1,
- blessings: blessingsA
- }
- },
- {
- type: 'delete',
- value: {
- cacheId: 1,
- deleteAfter: 2
- },
- },
- {
- type: 'blessingsFromId',
- cacheId: 1,
- expected: blessingsA
- },
- {
- type: 'blessingsFromId',
- cacheId: 1,
- expected: blessingsA
- },
- {
- type: 'confirmDelete',
- cacheId: 1
- }
- ];
-
- testCache(t, messages);
-});
-
-test('Blessing cache - add after delete', function(t) {
- var blessingsA = {
- publicKey: 'A'
- };
- var messages = [
- {
- type: 'delete',
- value: {
- cacheId: 1,
- deleteAfter: 1
- },
- },
- {
- type: 'add',
- value: {
- cacheId: 1,
- blessings: blessingsA
- }
- },
- {
- type: 'blessingsFromId',
- cacheId: 1,
- expected: blessingsA
- },
- {
- type: 'confirmDelete',
- cacheId: 1
- }
- ];
-
- testCache(t, messages);
-});
-
-test('Blessing cache - multiple entries', function(t) {
- var blessingsA = {
- publicKey: 'A'
- };
- var blessingsB = {
- publicKey: 'B'
- };
- var blessingsC = {
- publicKey: 'C'
- };
- var messages = [
- {
- type: 'add',
- value: {
- cacheId: 1,
- blessings: blessingsA
- }
- },
- {
- type: 'add',
- value: {
- cacheId: 2,
- blessings: blessingsB
- }
- },
- {
- type: 'blessingsFromId',
- cacheId: 2,
- expected: blessingsB
- },
- {
- type: 'blessingsFromId',
- cacheId: 1,
- expected: blessingsA
- },
- {
- type: 'delete',
- value: {
- cacheId: 1,
- deleteAfter: 1
- },
- },
- {
- type: 'confirmDelete',
- cacheId: 1
- },
- {
- type: 'add',
- value: {
- cacheId: 3,
- blessings: blessingsC
- }
- },
- {
- type: 'delete',
- value: {
- cacheId: 2,
- deleteAfter: 3
- },
- },
- {
- type: 'blessingsFromId',
- cacheId: 2,
- expected: blessingsB
- },
- {
- type: 'blessingsFromId',
- cacheId: 3,
- expected: blessingsC
- },
- {
- type: 'delete',
- value: {
- cacheId: 3,
- deleteAfter: 1
- },
- },
- {
- type: 'confirmDelete',
- cacheId: 3
- },
- {
- type: 'blessingsFromId',
- cacheId: 2,
- expected: blessingsB
- },
- {
- type: 'confirmDelete',
- cacheId: 2
- }
- ];
-
- testCache(t, messages);
-});
-
-test('Blessing cache handles typed BlessingsId objects', function(t) {
- var blessingsA = {
- publicKey: 'A'
- };
- var messages = [
- {
- type: 'add',
- value: {
- cacheId: 1,
- blessings: blessingsA
- }
- },
- {
- type: 'blessingsFromId',
- cacheId: new principal.BlessingsId(1),
- expected: blessingsA
- }
- ];
-
- testCache(t, messages);
-});
-
-test('Blessing cache handles zero blessing id', function(t) {
- var messages = [
- {
- type: 'blessingsFromId',
- cacheId: new principal.BlessingsId(0),
- expected: null
- }
- ];
-
- testCache(t, messages);
-});
-
-/**
- * Tests the cache by handling a sequence of messages.
- * @private
- */
-function testCache(t, messages) {
- var cache = new BlessingsCache();
- var promises = [];
- messages.forEach(function(message, index) {
- // Wait for the previous messages to finish unless dontWaitPrevious is
- // specified.
- var preCondPromise = Promise.all(promises);
- if (message.dontWaitPrevious) {
- preCondPromise = Promise.resolve();
- }
-
- var result = preCondPromise.then(function() {
- return handleCacheTestMessage(t, cache, message, index);
- }).catch(function(err) {
- t.fail('Error in message ' + index + ': ' + err);
- });
- promises.push(result);
- });
-
- // Wait for all promises to complete.
- Promise.all(promises).then(function() {
- t.end();
- }).catch(function(err) {
- t.end(err);
- });
-}
-
-function handleCacheTestMessage(t, cache, message, index) {
- if (message.type === 'add') {
- var addMsg = new principal.BlessingsCacheAddMessage(message.value);
- return cache.addBlessings(addMsg);
- } else if (message.type === 'delete') {
- var delMsg = new principal.BlessingsCacheDeleteMessage(message.value);
- return cache.deleteBlessings(delMsg);
- } else if (message.type === 'confirmDelete') {
- t.ok(cache._entries, 'Entries table should exist');
- t.notOk(message.cacheId in cache._entries,
- 'Cache entry not deleted correctly on message ' + index);
- } else if (message.type === 'blessingsFromId') {
- return cache.blessingsFromId(message.cacheId).then(function(blessings) {
- var expected = null;
- if (message.expected !== null) {
- expected = new principal.JsBlessings(message.expected);
- }
- t.deepEqual(blessings, expected,
- 'Should get expected blessings on message ' + index);
- });
- } else {
- throw new Error('unknown message type');
- }
-}
diff --git a/test/unit/test-caveat-validator-registry.js b/test/unit/test-caveat-validator-registry.js
index f43a275..67fbf9d 100644
--- a/test/unit/test-caveat-validator-registry.js
+++ b/test/unit/test-caveat-validator-registry.js
@@ -6,12 +6,13 @@
var CaveatValidatorRegistry =
require('../../src/security/caveat-validator-registry');
var context = require('../../src/context');
+var SecurityCall = require('../../src/security/call');
var caveats = require('../../src/security/caveats');
var testCaveats = require('../vdl-out/javascript-test/security/caveat');
function getMockSecurityCall() {
- return {
+ return new SecurityCall({
method: '',
suffix: '',
methodTags: [],
@@ -27,7 +28,9 @@
remoteBlessingStrings: [],
localEndpoint: '',
remoteEndpoint: ''
- };
+ },
+ null, // controller
+ context.Context());
}
diff --git a/test/unit/test-standard-caveat-validators.js b/test/unit/test-standard-caveat-validators.js
index 41e545e..0285090 100644
--- a/test/unit/test-standard-caveat-validators.js
+++ b/test/unit/test-standard-caveat-validators.js
@@ -8,11 +8,12 @@
var caveats = require('../../src/security/caveats');
var vdlSecurity = require('../../src/gen-vdl/v.io/v23/security');
var context = require('../../src/context');
+var SecurityCall = require('../../src/security/call');
var Time = require('../../src/gen-vdl/v.io/v23/vdlroot/time').Time;
var vdl = require('../../src/vdl');
function getMockSecurityCall() {
- return {
+ return new SecurityCall({
method: 'aMethod', // only field currently used
suffix: '',
methodTags: [],
@@ -28,7 +29,9 @@
remoteBlessingStrings: [],
localEndpoint: '',
remoteEndpoint: ''
- };
+ },
+ null, // controller
+ context.Context());
}
function assertValidation(t, cavType, val, cb) {