| // 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 Blessings = require('./blessings'); |
| 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 Blessings~cb |
| * @param {Error} err If set, the error that occured |
| * @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 |
| * {@link module:vanadium~Runtime#principal} |
| * @constructor |
| * @property {module:vanadium.security~Blessings} defaultBlessings The default |
| * blessings for this principal. |
| * @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 Cavaeats to |
| * restrict the blessing. |
| * @param {Blessings~cb} cb an optional callback that will return the blessing |
| * @return {Promise} 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); |
| |
| var controller = this._controller; |
| this._controller.bless.call(controller, ctx, publicKey, |
| blessings._id, extension, caveats) |
| .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; |
| }; |
| |
| /** |
| * 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 Cavaeats to |
| * restrict the blessing. |
| * @param {Blessings~cb} cb an optional callback that will return the blessing |
| * @return {Promise} 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.call(this._controller, ctx, name, caveats) |
| .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; |
| }; |
| |
| /** |
| * 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 {Blessings~cb} cb an optional callback that will return the blessing |
| * handle |
| * @return {Promise} a promise (resolves with no value) |
| */ |
| 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.call(this._controller, |
| ctx, blessings._id, cb); |
| }; |
| |
| Principal.prototype._loadDefaultBlessings = function() { |
| var self = this; |
| return this._controller.getDefaultBlessings(this._ctx). |
| then(function(res) { |
| self.defaultBlessings = res; |
| }); |
| }; |
| module.exports = Principal; |