Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

iam: Implement support #1193

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file added docs/json/master/iam/.gitkeep
Empty file.
3 changes: 3 additions & 0 deletions docs/toc.json
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@
"title": "Transaction",
"type": "datastore/transaction"
}]
}, {
"title": "IAM",
"type": "iam"
}, {
"title": "Logging",
"type": "logging",
Expand Down
1 change: 1 addition & 0 deletions lib/common/service.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ function Service(config, options) {
this.getCredentials = this.makeAuthenticatedRequest.getCredentials;
this.globalInterceptors = arrify(options.interceptors_);
this.interceptors = [];
this.options = options;
this.projectId = options.projectId;
this.projectIdRequired = config.projectIdRequired !== false;
}
Expand Down
123 changes: 71 additions & 52 deletions lib/pubsub/iam.js → lib/iam/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/

/*!
* @module pubsub/iam
* @module iam
*/

'use strict';
Expand All @@ -30,84 +30,111 @@ var nodeutil = require('util');
*/
var GrpcService = require('../common/grpc-service.js');

/**
* @type {module:common/serviceObject}
* @private
*/
var ServiceObject = require('../common/service-object.js');

/**
* @type {module:common/util}
* @private
*/
var util = require('../common/util.js');

/*! Developer Documentation
*
* @param {module:pubsub} pubsub - PubSub Object.
* @param {object} config - Configuration object.
* @param {string} config.baseUrl - The base URL to apply to API requests.
* @param {string} config.id - The name of the topic or subscription.
* @param {*=} scope - A Service object that supports IAM. We can use this to
* get the resource ID.
*/
/**
* [IAM (Identity and Access Management)](https://cloud.google.com/pubsub/access_control)
* [IAM (Identity and Access Management)](https://cloud.google.com/iam/docs)
* allows you to set permissions on invidual resources and offers a wider range
* of roles: editor, owner, publisher, subscriber, and viewer. This gives you
* greater flexibility and allows you to set more fine-grained access control.
*
* For example:
* * Grant access on a per-topic or per-subscription basis, rather than for
* the whole Cloud project.
* * Grant access with limited capabilities, such as to only publish messages
* to a topic, or to only to consume messages from a subscription, but not
* to delete the topic or subscription.
*
*
* *The IAM access control features described in this document are Beta,
* including the API methods to get and set IAM policies, and to test IAM
* permissions. Google Cloud Pub/Sub's use of IAM features is not covered by any
* SLA or deprecation policy, and may be subject to backward-incompatible
* changes.*
*
* @constructor
* @alias module:pubsub/iam
* @alias module:iam
*
* @resource [Access Control Overview]{@link https://cloud.google.com/pubsub/access_control}
* @resource [What is Cloud IAM?]{@link https://cloud.google.com/iam/}
* @param {string} id - The ID of the resource.
* @param {object} options - [Configuration object](#/docs/?method=gcloud).
*
* @example
* var pubsub = gcloud.pubsub({
* var gcloud = require('gcloud')({
* projectId: 'grape-spaceship-123',
* keyFilename: '/path/to/keyfile.json'
* });
*
* var iam = gcloud.iam('resource-id');
*
* //-
* // You can also access the IAM functionality of a service object you have
* // already created.
* //-
* var pubsub = gcloud.pubsub();
*
* var topic = pubsub.topic('my-topic');
* // topic.iam
* // topic.iam;
*
* var subscription = pubsub.subscription('my-subscription');
* // subscription.iam
* var subscription = topic.subscription('my-subscription');
* // subscription.iam;
*/
function IAM(pubsub, id) {
function IAM(resource, options) {
var isServiceObject = resource instanceof ServiceObject;

if (isServiceObject) {
options = options || resource.parent.options;
}

if (!(this instanceof IAM)) {
options = util.normalizeArguments(this, options);
return new IAM(resource, options);
}

var baseUrl;
var id = resource;

if (isServiceObject) {
var leadingProtocol = new RegExp('^https*://');
var trailingSlashes = new RegExp('/*$');

baseUrl = resource.parent.baseUrl
.replace(leadingProtocol, '')
.replace(trailingSlashes, '');

id = resource.id;
} else {
// @todo figure out baseUrl
}

var config = {
baseUrl: pubsub.defaultBaseUrl_,
baseUrl: baseUrl,
service: 'iam',
apiVersion: 'v1',
scopes: [
'https://www.googleapis.com/auth/pubsub',
'https://www.googleapis.com/auth/cloud-platform'
]
};

this.id = id;

GrpcService.call(this, config, pubsub.options);
GrpcService.call(this, config, options);
}

nodeutil.inherits(IAM, GrpcService);

/**
* Get the IAM policy
* Get the IAM policy.
*
* @param {function} callback - The callback function.
* @param {?error} callback.err - An error returned while making this request.
* @param {object} callback.policy - The [policy](https://cloud.google.com/pubsub/reference/rest/Shared.Types/Policy).
* @param {object} callback.policy - The [Policy object](https://cloud.google.com/iam/reference/rest/v1/Policy).
* @param {object} callback.apiResponse - The full API response.
*
* @resource [Topics: getIamPolicy API Documentation]{@link https://cloud.google.com/pubsub/reference/rest/v1/projects.topics/getIamPolicy}
* @resource [Subscriptions: getIamPolicy API Documentation]{@link https://cloud.google.com/pubsub/reference/rest/v1/projects.subscriptions/getIamPolicy}
* @resource [Policy]{@link https://cloud.google.com/iam/reference/rest/v1/Policy}
*
* @example
* topic.iam.getPolicy(function(err, policy, apiResponse) {});
*
* subscription.iam.getPolicy(function(err, policy, apiResponse) {});
* iam.getPolicy(function(err, policy, apiResponse) {});
*/
IAM.prototype.getPolicy = function(callback) {
var protoOpts = {
Expand All @@ -123,11 +150,11 @@ IAM.prototype.getPolicy = function(callback) {
};

/**
* Set the IAM policy
* Set the IAM policy.
*
* @throws {Error} If no policy is provided.
*
* @param {object} policy - The [policy](https://cloud.google.com/pubsub/reference/rest/Shared.Types/Policy).
* @param {object} policy - The [Policy object](https://cloud.google.com/iam/reference/rest/v1/Policy).
* @param {array=} policy.bindings - Bindings associate members with roles.
* @param {object[]=} policy.rules - Rules to be applied to the policy.
* @param {string=} policy.etag - Etags are used to perform a read-modify-write.
Expand All @@ -136,9 +163,7 @@ IAM.prototype.getPolicy = function(callback) {
* @param {object} callback.policy - The updated policy.
* @param {object} callback.apiResponse - The full API response.
*
* @resource [Topics: setIamPolicy API Documentation]{@link https://cloud.google.com/pubsub/reference/rest/v1/projects.topics/setIamPolicy}
* @resource [Subscriptions: setIamPolicy API Documentation]{@link https://cloud.google.com/pubsub/reference/rest/v1/projects.subscriptions/setIamPolicy}
* @resource [Policy]{@link https://cloud.google.com/pubsub/reference/rest/Shared.Types/Policy}
* @resource [Policy]{@link https://cloud.google.com/iam/reference/rest/v1/Policy}
*
* @example
* var myPolicy = {
Expand All @@ -150,9 +175,7 @@ IAM.prototype.getPolicy = function(callback) {
* ]
* };
*
* topic.iam.setPolicy(myPolicy, function(err, policy, apiResponse) {});
*
* subscription.iam.setPolicy(myPolicy, function(err, policy, apiResponse) {});
* iam.setPolicy(myPolicy, function(err, policy, apiResponse) {});
*/
IAM.prototype.setPolicy = function(policy, callback) {
if (!is.object(policy)) {
Expand Down Expand Up @@ -186,17 +209,13 @@ IAM.prototype.setPolicy = function(policy, callback) {
* is allowed
* @param {object} callback.apiResponse - The full API response.
*
* @resource [Topics: testIamPermissions API Documentation]{@link https://cloud.google.com/pubsub/reference/rest/v1/projects.topics/testIamPermissions}
* @resource [Subscriptions: testIamPermissions API Documentation]{@link https://cloud.google.com/pubsub/reference/rest/v1/projects.subscriptions/testIamPermissions}
* @resource [Permissions Reference]{@link https://cloud.google.com/pubsub/access_control#permissions}
*
* @example
* //-
* // Test a single permission.
* //-
* var test = 'pubsub.topics.update';
*
* topic.iam.testPermissions(test, function(err, permissions, apiResponse) {
* iam.testPermissions(test, function(err, permissions, apiResponse) {
* console.log(permissions);
* // {
* // "pubsub.topics.update": true
Expand All @@ -211,7 +230,7 @@ IAM.prototype.setPolicy = function(policy, callback) {
* 'pubsub.subscriptions.update'
* ];
*
* subscription.iam.testPermissions(tests, function(err, permissions) {
* iam.testPermissions(tests, function(err, permissions) {
* console.log(permissions);
* // {
* // "pubsub.subscriptions.consume": true,
Expand Down
20 changes: 20 additions & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,26 @@ var apis = {
*/
dns: require('./dns'),

/**
* [IAM (Identity and Access Management)](https://cloud.google.com/iam/docs)
* allows you to set permissions on invidual resources and offers a wider
* range of roles: editor, owner, publisher, subscriber, and viewer. This
* gives you greater flexibility and allows you to set more fine-grained
* access control.
*
* @type {module:iam}
*
* @return {module:iam}
*
* @example
* var gcloud = require('gcloud');
* var iam = gcloud.iam('resource-id', {
* projectId: 'grape-spaceship-123',
* keyFilename: '/path/to/keyfile.json'
* });
*/
iam: require('./iam'),

/**
* The [Google Prediction API](https://cloud.google.com/prediction/docs/getting-started)
* provides pattern-matching and machine learning capabilities. Given a set of
Expand Down
20 changes: 13 additions & 7 deletions lib/pubsub/subscription.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ var prop = require('propprop');
var GrpcServiceObject = require('../common/grpc-service-object.js');

/**
* @type {module:pubsub/iam}
* @type {module:iam}
* @private
*/
var IAM = require('./iam.js');
var IAM = require('../iam/index.js');

/**
* @type {module:common/util}
Expand Down Expand Up @@ -284,7 +284,7 @@ function Subscription(pubsub, options) {
* any SLA or deprecation policy, and may be subject to backward-incompatible
* changes.*
*
* @mixes module:pubsub/iam
* @mixes module:iam
*
* @resource [Access Control Overview]{@link https://cloud.google.com/pubsub/access_control}
* @resource [What is Cloud IAM?]{@link https://cloud.google.com/iam/}
Expand All @@ -293,11 +293,17 @@ function Subscription(pubsub, options) {
* //-
* // Get the IAM policy for your subscription.
* //-
* subscription.iam.getPolicy(function(err, policy) {
* console.log(policy);
* });
*/
this.iam = new IAM(pubsub, this.name);
var iam;
Object.defineProperty(this, 'iam', {

This comment was marked as spam.

get: function() {
if (!iam) {
iam = new IAM(this);
}

return iam;
}
});

this.listenForEvents_();
}
Expand Down
17 changes: 13 additions & 4 deletions lib/pubsub/topic.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@ var prop = require('propprop');
var util = require('../common/util.js');

/**
* @type {module:pubsub/iam}
* @type {module:iam}
* @private
*/
var IAM = require('./iam.js');
var IAM = require('../iam/index.js');

/**
* @type {module:common/grpcServiceObject}
Expand Down Expand Up @@ -174,7 +174,7 @@ function Topic(pubsub, name) {
* any SLA or deprecation policy, and may be subject to backward-incompatible
* changes.*
*
* @mixes module:pubsub/iam
* @mixes module:iam
*
* @resource [Access Control Overview]{@link https://cloud.google.com/pubsub/access_control}
* @resource [What is Cloud IAM?]{@link https://cloud.google.com/iam/}
Expand All @@ -187,7 +187,16 @@ function Topic(pubsub, name) {
* console.log(policy);
* });
*/
this.iam = new IAM(pubsub, this.name);
var iam;
Object.defineProperty(this, 'iam', {
get: function() {
if (!iam) {
iam = new IAM(this);
}

return iam;
}
});
}

nodeutil.inherits(Topic, GrpcServiceObject);
Expand Down
9 changes: 7 additions & 2 deletions scripts/docs.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ var IGNORE = [
'./lib/datastore/entity.js',
'./lib/datastore/pb.js',
'./lib/datastore/request.js',
'./lib/pubsub/iam.js',
'./lib/storage/acl.js'
];

Expand Down Expand Up @@ -268,7 +267,13 @@ function getMixinMethods(comments) {
}).map(function(block) {
var mixin = getTagsByType(block, 'mixes')[0];
var mixinFile = path.join('./lib', mixin.string.replace('module:', '') + '.js');
var mixinContents = fs.readFileSync(mixinFile, 'utf8', true);
var mixinContents;
try {
mixinContents = fs.readFileSync(mixinFile, 'utf8', true);
} catch (e) {
mixinFile = mixinFile.replace('.js', '/index.js');
mixinContents = fs.readFileSync(mixinFile, 'utf8', true);
}
var docs = parseFile(mixinFile, mixinContents);
var methods = docs.methods.filter(function(method) {
return method.type === 'instance';
Expand Down
Loading