UNPKG

coam-client

Version:
657 lines (561 loc) 20.7 kB
"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;