blob: dfd697cf5d6ead3f72cc1820ba43fe5fae53054a [file] [log] [blame]
// 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 Principal stub for vanadium principals
* @private
*/
var Deferred = require('../lib/deferred');
var BlessingStore = require('./blessingstore');
var verror = require('../gen-vdl/v.io/v23/verror');
/**
* A callback that is called with either an error or a
* [Blessings]{@link module:vanadium.security~Blessings} object.
* @callback module:vanadium.security~Principal~blessingsCb
* @param {Error} err If set, the error that occurred
* @param {module:vanadium.security~Blessings} blessings The blessings result.
*/
/**
* @summary Principal represents an entity capable of making or receiving RPCs.
* @description <p>Principal represents an entity capable of making or receiving
* RPCs. Principals have a unique (public, private) key pair, have blessings
* bound to them and can bless other principals.</p>
* <p>This constructor should not be used explicitly. Instead, use the
* principal property on the [runtime]{@link module:vanadium~Runtime}.
* @constructor
* @property {module:vanadium.security~BlessingStore} blessingStore The
* blessing store.
* @inner
* @memberof module:vanadium.security
*/
function Principal(ctx, controller) {
this._controller = controller;
this._ctx = ctx;
this.blessingStore = new BlessingStore(controller);
}
/**
* <p>Bless binds extensions of blessings held by this principal to
* another principal (represented by its public key).</p>
*
* <p>For example, a principal with the blessings "google/alice"
* and "v23/alice" can bind the blessings "google/alice/friend"
* and "v23/alice/friend" to another principal using:</p>
* <pre>
* bless(ctx, <other public key>, <google/alice, v23/alice>, 'friend', ...)
* </pre>
* @param {module:vanadium.context.Context} ctx The context.
* @param {string} publicKey The public key to bless.
* @param {module:vanadium.security~Blessings} blessing The blessings.
* @param {string} extension The extension for the blessing.
* @param {...module:vanadium.security.Caveat} caveats An array of Caveats to
* restrict the blessing.
* @param {module:vanadium.security~Principal~blessingsCb} cb An optional
* callback that will return the blessing.
* @return {Promise<module:vanadium.security~Blessings>} A promise that will be
* resolved with the blessing.
*/
Principal.prototype.bless = function(ctx, publicKey, blessings,
extension, firstCaveat /*, ...moreCaveats, cb*/) {
// Extract the callback.
var cb;
var args = Array.prototype.slice.call(arguments);
if (args.length > 0 &&
typeof args[args.length - 1] === 'function') {
cb = args[args.length - 1];
args.pop();
}
var def = new Deferred(cb);
// We must have at least one caveat.
if (typeof firstCaveat !== 'object') {
def.reject('At least one caveat must be specified. To bless without ' +
'adding restrictions, use UnconstrainedUseCaveat');
return def.promise;
}
var caveats = args.slice(4);
this._controller.bless(ctx, publicKey, blessings, extension, caveats)
.then(function(blessings) {
def.resolve(blessings);
}).catch(function(err) {
def.reject(err);
});
return def.promise;
};
/**
* BlessSelf creates a blessing with the provided name for this principal.
* @param {module:vanadium.context.Context} ctx The context.
* @param {string} name The name for the blessing.
* @param {...module:vanadium.security.Caveat} caveats An array of Caveats to
* restrict the blessing.
* @param {module:vanadium.security~Principal~blessingsCb} cb An optional
* callback that will return the blessing.
* @return {Promise<module:vanadium.security~Blessings>} A promise that will be
* resolved with the blessing.
*/
Principal.prototype.blessSelf = function(ctx, name /*, ...caveats, cb*/) {
// Extract the callback.
var cb;
var args = Array.prototype.slice.call(arguments);
if (args.length > 0 &&
typeof args[args.length - 1] === 'function') {
cb = args[args.length - 1];
args.pop();
}
var def = new Deferred(cb);
var caveats = args.slice(2);
var controller = this._controller;
controller.blessSelf(ctx, name, caveats)
.then(function(blessings) {
def.resolve(blessings);
}).catch(function(err) {
def.reject(err);
});
return def.promise;
};
/**
* Add the provided blessing as a root.
* @param {module:vanadium.context.Context} ctx The context.
* @param {module:vanadium.security~Blessings} blessings The blessings object.
* @param {module:vanadium~voidCb} cb If provided, the function
* will be called on completion.
* @return {Promise<void>} A promise that will be resolved/reject on completion.
*/
Principal.prototype.addToRoots = function(
ctx, blessings, cb) {
var def;
if (blessings === undefined) {
def = new Deferred(cb);
def.reject(new verror.InternalError(this._ctx,
'Blessings handle not specified'));
return def.promise;
}
return this._controller.addToRoots(ctx, blessings, cb);
};
module.exports = Principal;