coam-client
Version:
A thin client for COAM service
657 lines (561 loc) • 20.7 kB
JavaScript
"use strict";
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
var axios = require('axios');
var axiosRetry = require('axios-retry');
var _require = require('pope'),
pope = _require.pope;
var DEFAULT_BASE_URL = 'https://api.cimpress.io';
var CoamClient = /*#__PURE__*/function () {
function CoamClient(options) {
var _this = this;
_classCallCheck(this, CoamClient);
var opts = options || {};
this.baseUrl = opts.baseUrl || DEFAULT_BASE_URL;
this.timeout = Number.isInteger(opts.timeout) ? opts.timeout : 8000;
this.accessToken = opts.accessToken || undefined;
this.retryAttempts = Number.isInteger(opts.retryAttempts) ? opts.retryAttempts : 2;
this.retryDelayInMs = Number.isInteger(opts.retryDelayInMs) ? opts.retryDelayInMs : 200;
this.retryOnForbidden = 'retryOnForbidden' in opts ? opts.retryOnForbidden : true;
this.debugFunction = 'debugFunction' in opts ? opts.debugFunction : undefined; // eslint-disable-next-line
this.errorFunction = 'errorFunction' in opts ? opts.errorFunction : console.error;
this.skipCache = 'skipCache' in opts ? opts.skipCache : false;
this.logPrefix = '[CoamClient]';
var validOptions = ['baseUrl', 'accessToken', 'timeout', 'retryAttempts', 'retryDelayInMs', 'retryOnForbidden', 'debugFunction', 'errorFunction', 'skipCache'];
Object.keys(opts).forEach(function (passedOption) {
if (validOptions.indexOf(passedOption) === -1) {
// eslint-disable-next-line no-console
_this.__logError("".concat(_this.logPrefix, " Option '").concat(passedOption, "' is not understood and will be ignored."));
}
});
this.instance = axios.create({
baseURL: this.baseUrl,
timeout: this.timeout
});
this.instance.interceptors.response.use(function (response) {
return response;
}, function (error) {
var newError = error && error.response && {
data: error.response.data,
status: error.response.status,
headers: error.response.headers
} || error.message && {
message: error.message,
code: error.code,
stack: error.stack
} || error;
throw newError;
});
if (this.retryAttempts > 0) {
if (typeof axiosRetry !== 'function') {
axiosRetry = axiosRetry["default"];
}
axiosRetry(this.instance, {
retries: this.retryAttempts,
retryCondition: function retryCondition(error) {
if (axiosRetry.isNetworkOrIdempotentRequestError(error)) {
return true;
}
if (_this.retryOnForbidden && error && error.response && error.response.status === 403) {
return true;
} // do not retry
return false;
},
retryDelay: function retryDelay() {
return _this.retryDelayInMs;
},
shouldResetTimeout: true
});
}
}
_createClass(CoamClient, [{
key: "__exec",
value: function __exec(data) {
var _this2 = this;
if (this.skipCache && data.method === 'GET') {
data.params = Object.assign(data.params || {}, {
skipCache: Math.random()
});
}
return this.instance.request(data).then(function (response) {
return response.data;
})["catch"](function (err) {
_this2.__logError(err);
throw err;
});
}
}, {
key: "__config",
value: function __config(data) {
return Object.assign({}, {
headers: {
Authorization: "Bearer ".concat(this.accessToken)
}
}, data);
}
}, {
key: "__buildUrl",
value: function __buildUrl(urlPattern, dataToEncode) {
var encoded = {};
Object.keys(dataToEncode).forEach(function (k) {
return encoded[k] = encodeURIComponent(dataToEncode[k]);
});
return pope(urlPattern, encoded);
}
}, {
key: "__logDebug",
value: function __logDebug() {
if (this.debugFunction) {
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
this.debugFunction.apply(null, args);
}
}
}, {
key: "__logError",
value: function __logError() {
if (this.errorFunction) {
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
args[_key2] = arguments[_key2];
}
this.errorFunction.apply(null, args);
}
}
}, {
key: "buildGroupUrlFromId",
value: function buildGroupUrlFromId(groupId) {
return "".concat(this.baseUrl, "/auth/access-management/v1/groups/").concat(groupId);
}
}, {
key: "hasPermission",
value: function hasPermission(principal, resourceType, resourceIdentifier, permission) {
var url = this.__buildUrl("/auth/access-management/v1/principals/{{principal}}/permissions/{{resourceType}}/{{resourceIdentifier}}/{{permission}}", {
principal: principal,
resourceType: resourceType,
resourceIdentifier: resourceIdentifier,
permission: permission
});
var data = this.__config({
url: url,
method: 'GET'
});
return this.__exec(data).then(function () {
return Promise.resolve(true);
})["catch"](function (e) {
// COAM returns a 404 if the principal does not have access to a resource
if (e.status === 404) {
return false;
} // for all other errors, we want to throw an exception so that clients
// can retry instead of assuming the user does not have access
throw e;
});
}
}, {
key: "grantRoleToPrincipal",
value: function grantRoleToPrincipal(groupUrl, principal, roleName) {
var _this3 = this;
return this.getGroupInfo(groupUrl).then(function (groupInfo) {
if (!groupInfo) {
return Promise.reject(new Error('Failed to retrieve template COAM group.'));
}
return _this3.addGroupMember(groupInfo.id, principal, false).then(function () {
return _this3.modifyUserRoles(groupInfo.id, principal, {
'add': [roleName]
});
});
});
}
}, {
key: "getGroupInfo",
value: function getGroupInfo(groupUrl) {
var data = this.__config({
url: groupUrl,
method: 'GET',
params: {
canonicalize: 'true'
}
});
return this.__exec(data);
}
}, {
key: "setAdminFlag",
value: function setAdminFlag(groupId, principal, isAdmin) {
var url = this.__buildUrl("/auth/access-management/v1/groups/{{groupId}}/members/{{principal}}", {
groupId: groupId,
principal: principal
});
var data = this.__config({
url: url,
method: 'PATCH',
data: {
'is_admin': isAdmin
}
});
return this.__exec(data);
}
}, {
key: "removeUserRole",
value: function removeUserRole(groupId, principal, role) {
var url = this.__buildUrl("/auth/access-management/v1/groups/{{groupId}}/members/{{principal}}/roles", {
groupId: groupId,
principal: principal
});
var data = this.__config({
url: url,
method: 'PATCH',
data: {
'remove': [role]
}
});
return this.__exec(data);
}
}, {
key: "addUserRole",
value: function addUserRole(groupId, principal, role) {
var url = this.__buildUrl("/auth/access-management/v1/groups/{{groupId}}/members/{{principal}}/roles", {
groupId: groupId,
principal: principal
});
var data = this.__config({
url: url,
method: 'PATCH',
data: {
'add': [role]
}
});
return this.__exec(data);
}
}, {
key: "group56",
value: function group56(principal) {
var url = this.__buildUrl("/auth/access-management/v1/principals/{{principal}}/groups", {
principal: principal
});
var data = this.__config({
url: url,
method: 'GET'
});
return this.__exec(data).then(function (data) {
return !!data.groups.find(function (a) {
return a.id === '56';
});
});
}
}, {
key: "modifyUserRoles",
value: function modifyUserRoles(groupId, principal, rolesChanges) {
var url = this.__buildUrl("/auth/access-management/v1/groups/{{groupId}}/members/{{principal}}/roles", {
groupId: groupId,
principal: principal
});
var data = this.__config({
url: url,
method: 'PATCH',
data: rolesChanges
});
return this.__exec(data);
}
}, {
key: "addGroupMember",
value: function addGroupMember(groupId, principal, isAdmin) {
var url = this.__buildUrl("/auth/access-management/v1/groups/{{groupId}}/members", {
groupId: groupId,
principal: principal
});
var data = this.__config({
url: url,
method: 'PATCH',
data: {
'add': [{
is_admin: !!isAdmin,
principal: principal
}]
},
params: {
canonicalize: true
}
});
return this.__exec(data);
}
}, {
key: "removeGroupMember",
value: function removeGroupMember(groupId, principal) {
var url = this.__buildUrl("/auth/access-management/v1/groups/{{groupId}}/members", {
groupId: groupId
});
var data = this.__config({
url: url,
method: 'PATCH',
data: {
'remove': [principal]
}
});
return this.__exec(data);
}
}, {
key: "getRoles",
value: function getRoles() {
var data = this.__config({
url: "/auth/access-management/v1/roles",
method: 'GET'
});
return this.__exec(data);
}
}, {
key: "findPrincipals",
value: function findPrincipals(query) {
if (!query || query.length === 0) {
return Promise.resolve([]);
}
var data = this.__config({
url: '/auth/access-management/v1/search/canonicalPrincipals/bySubstring',
method: 'GET',
params: {
q: query,
canonicalize: true
}
}); // [{user_id / name / email}]
return this.__exec(data).then(function (p) {
return p.canonical_principals;
});
}
}, {
key: "getPrincipal",
value: function getPrincipal(principal) {
var url = this.__buildUrl("/auth/access-management/v1/principals/{{principal}}", {
principal: principal
});
var data = this.__config({
url: url,
method: 'GET'
});
return this.__exec(data);
}
}, {
key: "createGroup",
value: function createGroup(name, description) {
var data = this.__config({
url: '/auth/access-management/v1/groups',
method: 'POST',
data: {
name: name,
description: description
}
}); // [{user_id / name / email}]
return this.__exec(data);
}
}, {
key: "removeGroup",
value: function removeGroup(groupId) {
var url = this.__buildUrl("/auth/access-management/v1/groups/{{groupId}}", {
groupId: groupId
});
var data = this.__config({
url: url,
method: 'DELETE'
});
return this.__exec(data);
}
}, {
key: "findGroups",
value: function findGroups(resourceType, resourceIdentifier, accountId, forAccountId, relationAccountId, isEssentialGroup, offset, limit, q) {
var data = this.__config({
url: "/auth/access-management/v1/groups",
method: 'GET',
params: {
resource_type: resourceType,
resource_identifier: resourceIdentifier,
account_id: accountId,
for_account_id: forAccountId,
relation_account_id: relationAccountId,
is_essential_group: isEssentialGroup,
offset: offset,
limit: limit,
q: q
}
});
return this.__exec(data);
}
}, {
key: "removeResourceFromGroup",
value: function removeResourceFromGroup(groupId, resourceType, resourceId) {
var url = this.__buildUrl("/auth/access-management/v1/groups/{{groupId}}/resources", {
groupId: groupId
});
var data = this.__config({
url: url,
method: 'PATCH',
data: {
add: [],
remove: [{
resource_type: resourceType,
resource_identifier: resourceId
}]
}
});
return this.__exec(data);
}
}, {
key: "addResourceToGroup",
value: function addResourceToGroup(groupId, resourceType, resourceId) {
var url = this.__buildUrl("/auth/access-management/v1/groups/{{groupId}}/resources", {
groupId: groupId
});
var data = this.__config({
url: url,
method: 'PATCH',
data: {
add: [{
resource_type: resourceType,
resource_identifier: resourceId
}],
remove: []
}
});
return this.__exec(data);
}
}, {
key: "getUserPermissionsForResourceType",
value: function getUserPermissionsForResourceType(principal, resourceType) {
var include = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
var permissionFilters = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
var urlString = "/auth/access-management/v1/principals/{{principal}}/permissions/{{resourceType}}?include=".concat(include).concat(permissionFilters ? "&permissionFilter=".concat(permissionFilters.join(',')) : '');
var url = this.__buildUrl(urlString, {
principal: principal,
resourceType: resourceType
});
var data = this.__config({
url: url,
method: 'GET'
});
return this.__exec(data);
}
}, {
key: "getUserPermissionsForResourceTypes",
value: function getUserPermissionsForResourceTypes(principal, resourceTypes) {
var include = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
var permissionFilters = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
var urlString = "/auth/access-management/v1/principals/{{principal}}/permissions?resourceTypes=".concat(resourceTypes.join(','), "&include=").concat(include).concat(permissionFilters ? "&permissionFilter=".concat(permissionFilters.join(',')) : '');
var url = this.__buildUrl(urlString, {
principal: principal
});
var data = this.__config({
url: url,
method: 'GET'
});
return this.__exec(data);
}
}, {
key: "getUsersWithPermission",
value: function getUsersWithPermission(resourceType, resourceIdentifier, permission) {
var url = this.__buildUrl("/auth/access-management/v1/search/canonicalPrincipals/byPermission?resource_type={{resourceType}}".concat(resourceIdentifier ? '&resource_identifier={{resourceIdentifier}}' : '', "&permission={{permission}}"), {
resourceType: resourceType,
resourceIdentifier: resourceIdentifier,
permission: permission
});
var data = this.__config({
url: url,
method: 'GET'
}); // [{user_id / name / email}]
return this.__exec(data).then(function (p) {
return p.canonical_principals;
});
}
}, {
key: "getUsersWithResource",
value: function getUsersWithResource(resourceType, permissionFilters) {
var url = this.__buildUrl("/auth/access-management/v1/search/canonicalPrincipals/byResource?resource_type={{resourceType}}".concat(permissionFilters && permissionFilters.length > 0 ? '&permissionFilter={{commaSeparatedPermissionFilter}}' : ''), {
resourceType: resourceType,
commaSeparatedPermissionFilter: permissionFilters && permissionFilters.length > 0 && permissionFilters.join(',')
});
var data = this.__config({
url: url,
method: 'GET'
}); // [{canonical_principal / resource_type / is_client / permissions}]
return this.__exec(data);
}
}, {
key: "createGroupWithUser",
value: function () {
var _createGroupWithUser = _asyncToGenerator( /*#__PURE__*/_regenerator["default"].mark(function _callee(principalToCreateGroup, principalToAddToGroup, groupName, groupDescription, rolesToAdd, resourcesToAdd) {
var res, groupId, i, _i, resource;
return _regenerator["default"].wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return this.createGroup(groupName, groupDescription);
case 2:
res = _context.sent;
groupId = res.id;
_context.next = 6;
return this.addGroupMember(groupId, principalToAddToGroup);
case 6:
_context.next = 8;
return this.setAdminFlag(groupId, principalToAddToGroup, true);
case 8:
i = 0;
case 9:
if (!(i < rolesToAdd.length)) {
_context.next = 15;
break;
}
_context.next = 12;
return this.addUserRole(groupId, principalToAddToGroup, rolesToAdd[i]);
case 12:
i++;
_context.next = 9;
break;
case 15:
_i = 0;
case 16:
if (!(_i < resourcesToAdd.length)) {
_context.next = 23;
break;
}
resource = resourcesToAdd[_i];
_context.next = 20;
return this.addResourceToGroup(groupId, resource.resourceType, resource.resourceId);
case 20:
_i++;
_context.next = 16;
break;
case 23:
_context.prev = 23;
_context.next = 26;
return this.removeGroupMember(groupId, principalToCreateGroup);
case 26:
_context.next = 32;
break;
case 28:
_context.prev = 28;
_context.t0 = _context["catch"](23);
if (!(_context.t0.status !== 404)) {
_context.next = 32;
break;
}
throw _context.t0;
case 32:
return _context.abrupt("return", groupId);
case 33:
case "end":
return _context.stop();
}
}
}, _callee, this, [[23, 28]]);
}));
function createGroupWithUser(_x, _x2, _x3, _x4, _x5, _x6) {
return _createGroupWithUser.apply(this, arguments);
}
return createGroupWithUser;
}()
}]);
return CoamClient;
}();
module.exports = CoamClient;