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

ts: Annotate Iam types #461

Merged
merged 2 commits into from
Oct 17, 2018
Merged
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
212 changes: 142 additions & 70 deletions src/iam.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,100 @@ import * as arrify from 'arrify';
import {promisifyAll} from '@google-cloud/promisify';
import * as extend from 'extend';
import * as is from 'is';
import * as r from 'request';

import {Bucket} from './bucket';
import {normalize} from './util';

/**
* @typedef {object} GetPolicyOptions
* @property {string} [userProject] The ID of the project which will be billed for
* the request.
*/
export interface GetPolicyOptions {
userProject?: string;
}

/**
* @typedef {array} GetPolicyResponse
* @property {object} 0 The policy.
* @property {object} 1 The full API response.
*/
export type GetPolicyResponse = [object, r.Response];

/**
* @callback GetPolicyCallback
* @param {?Error} err Request error, if any.
* @param {object} acl The policy.
* @param {object} apiResponse The full API response.
*/
export interface GetPolicyCallback {
(err?: Error|null, acl?: object, apiResponse?: r.Response): void;
}

/**
* @typedef {object} SetPolicyOptions
* @param {string} [userProject] The ID of the project which will be
* billed for the request.
*/
export interface SetPolicyOptions {
userProject?: string;
}

/**
* @typedef {array} SetPolicyResponse
* @property {object} 0 The policy.
* @property {object} 1 The full API response.
*/
export type SetPolicyResponse = [object, r.Response];

/**
* @callback SetPolicyCallback
* @param {?Error} err Request error, if any.
* @param {object} acl The policy.
* @param {object} apiResponse The full API response.
*/
export interface SetPolicyCallback {
(err?: Error|null, acl?: object, apiResponse?: object): void;
}

/**
* @typedef {object} Policy
* @property {array} policy.bindings Bindings associate members with roles.
* @property {string} [policy.etag] Etags are used to perform a read-modify-write.
*/
export interface Policy {
bindings: string[];
etag?: string;
}

/**
* @typedef {array} TestIamPermissionsResponse
* @property {object} 0 A subset of permissions that the caller is allowed.
* @property {object} 1 The full API response.
*/
export type TestIamPermissionsResponse = [{[key: string]: boolean}, r.Response];

/**
* @callback TestIamPermissionsCallback
* @param {?Error} err Request error, if any.
* @param {object} acl A subset of permissions that the caller is allowed.
* @param {object} apiResponse The full API response.
*/
export interface TestIamPermissionsCallback {
(err?: Error|null, acl?: {[key: string]: boolean}|null,
apiResponse?: r.Response): void;
}

/**
* @typedef {object} TestIamPermissionsOptions Configuration options for Iam#testPermissions().
* @param {string} [userProject] The ID of the project which will be
* billed for the request.
*/
export interface TestIamPermissionsOptions {
userProject?: string;
}


/**
* Get and set IAM policies for your Cloud Storage bucket.
Expand Down Expand Up @@ -49,22 +141,6 @@ class Iam {
this.resourceId_ = 'buckets/' + bucket.getId();
}

/**
* @typedef {object} GetPolicyRequest
* @property {string} userProject The ID of the project which will be billed for
* the request.
*/
/**
* @typedef {array} GetPolicyResponse
* @property {object} 0 The policy.
* @property {object} 1 The full API response.
*/
/**
* @callback GetPolicyCallback
* @param {?Error} err Request error, if any.
* @param {object} acl The policy.
* @param {object} apiResponse The full API response.
*/
/**
* Get the IAM policy.
*
Expand Down Expand Up @@ -92,42 +168,31 @@ class Iam {
* region_tag:storage_view_bucket_iam_members
* Example of retrieving a bucket's IAM policy:
*/
getPolicy(options, callback?) {
if (is.fn(options)) {
callback = options;
options = {};
}
getPolicy(options?: GetPolicyOptions): Promise<GetPolicyResponse>;
getPolicy(options: GetPolicyOptions, callback: GetPolicyCallback): void;
getPolicy(callback: GetPolicyCallback): void;
getPolicy(
optionsOrCallback?: GetPolicyOptions|GetPolicyCallback,
callback?: GetPolicyCallback): Promise<GetPolicyResponse>|void {
const {options, callback: cb} =
normalize<GetPolicyOptions, GetPolicyCallback>(
optionsOrCallback, callback);

this.request_(
{
uri: '/iam',
qs: options,
},
callback);
cb!);
}

/**
* @typedef {array} SetPolicyResponse
* @property {object} 0 The policy.
* @property {object} 1 The full API response.
*/
/**
* @callback SetPolicyCallback
* @param {?Error} err Request error, if any.
* @param {object} acl The policy.
* @param {object} apiResponse The full API response.
*/
/**
* Set the IAM policy.
*
* @throws {Error} If no policy is provided.
*
* @param {object} policy The policy.
* @param {array} policy.bindings Bindings associate members with roles.
* @param {string} [policy.etag] Etags are used to perform a read-modify-write.
* @param {object} [options] Configuration opbject.
* @param {string} [options.userProject] The ID of the project which will be
* billed for the request.
* @param {Policy} policy The policy.
* @param {SetPolicyOptions} [options] Configuration opbject.
* @param {SetPolicyCallback} callback Callback function.
* @returns {Promise<SetPolicyResponse>}
*
Expand Down Expand Up @@ -167,15 +232,22 @@ class Iam {
* region_tag:storage_remove_bucket_iam_member
* Example of removing from a bucket's IAM policy:
*/
setPolicy(policy, options, callback?) {
setPolicy(policy: Policy, options?: SetPolicyOptions):
Promise<SetPolicyResponse>;
setPolicy(policy: Policy, callback: SetPolicyCallback): void;
setPolicy(
policy: Policy, options: SetPolicyOptions,
callback: SetPolicyCallback): void;
setPolicy(
policy: Policy, optionsOrCallback?: SetPolicyOptions|SetPolicyCallback,
callback?: SetPolicyCallback): Promise<SetPolicyResponse>|void {
if (!is.object(policy)) {
throw new Error('A policy object is required.');
}

if (is.fn(options)) {
callback = options;
options = {};
}
const {options, callback: cb} =
normalize<SetPolicyOptions, SetPolicyCallback>(
optionsOrCallback, callback);

this.request_(
{
Expand All @@ -188,29 +260,16 @@ class Iam {
policy),
qs: options,
},
callback);
cb);
}

/**
* @typedef {array} TestIamPermissionsResponse
* @property {object[]} 0 A subset of permissions that the caller is allowed.
* @property {object} 1 The full API response.
*/
/**
* @callback TestIamPermissionsCallback
* @param {?Error} err Request error, if any.
* @param {object[]} acl A subset of permissions that the caller is allowed.
* @param {object} apiResponse The full API response.
*/
/**
* Test a set of permissions for a resource.
*
* @throws {Error} If permissions are not provided.
*
* @param {string|string[]} permissions The permission(s) to test for.
* @param {object} [options] Configuration object.
* @param {string} [options.userProject] The ID of the project which will be
* billed for the request.
* @param {TestIamPermissionsOptions} [options] Configuration object.
* @param {TestIamPermissionsCallback} [callback] Callback function.
* @returns {Promise<TestIamPermissionsResponse>}
*
Expand Down Expand Up @@ -257,42 +316,55 @@ class Iam {
* const apiResponse = data[1];
* });
*/
testPermissions(permissions, options, callback?) {
testPermissions(
permissions: string|string[],
options?: TestIamPermissionsOptions): Promise<TestIamPermissionsResponse>;
testPermissions(
permissions: string|string[], callback: TestIamPermissionsCallback): void;
testPermissions(
permissions: string|string[], options: TestIamPermissionsOptions,
callback: TestIamPermissionsCallback): void;
testPermissions(
permissions: string|string[],
optionsOrCallback?: TestIamPermissionsOptions|TestIamPermissionsCallback,
callback?: TestIamPermissionsCallback):
Promise<TestIamPermissionsResponse>|void {
if (!is.array(permissions) && !is.string(permissions)) {
throw new Error('Permissions are required.');
}

if (is.fn(options)) {
callback = options;
options = {};
}
const {options, callback: cb} =
normalize<TestIamPermissionsOptions, TestIamPermissionsCallback>(
optionsOrCallback, callback);

const permissionsArray = arrify(permissions);

options = extend(
const req = extend(
{
permissions: arrify(permissions),
permissions: permissionsArray,
},
options);

this.request_(
{
uri: '/iam/testPermissions',
qs: options,
qs: req,
useQuerystring: true,
},
(err, resp) => {
if (err) {
callback(err, null, resp);
cb!(err, null, resp);
return;
}

const availablePermissions = arrify(resp.permissions);

const permissionsHash = permissions.reduce((acc, permission) => {

This comment was marked as spam.

const permissionsHash = permissionsArray.reduce((acc, permission) => {
acc[permission] = availablePermissions.indexOf(permission) > -1;
return acc;
}, {});

callback(null, permissionsHash, resp);
cb!(null, permissionsHash, resp);
});
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@
*/

export function normalize<T = {}, U = Function>(
optionsOrCallback?: {}|Function, cb?: Function) {
optionsOrCallback?: T|U, cb?: U) {
const options =
(typeof optionsOrCallback === 'object' ? optionsOrCallback : {}) as T;
const callback =
(typeof optionsOrCallback === 'function' ? optionsOrCallback : cb)!;
(typeof optionsOrCallback === 'function' ? optionsOrCallback : cb)! as U;
return {options, callback};
}