| // 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; |