import stampit from 'stampit'; import _ from 'lodash'; import {Meta, Model} from './base'; import {BaseQuerySet, Get, Create, BulkCreate, List, Delete} from '../querySet'; const UserQuerySet = stampit().compose( BaseQuerySet, Get, Create, Delete, BulkCreate, List ).methods({ /** * Gets a user's groups. * @memberOf UserQuerySet * @instance * @param {Object} properties lookup properties used for path resolving * @returns {Promise} * @example {@lang javascript} * User.please().getGroups({id: 1, instanceName: 'test-one'}).then(function(groups) {}); */ getGroups(properties = {}) { const {Group} = this.getConfig(); this.properties = _.assign({}, this.properties, properties); return Group.please().getUserGroups(this.properties); }, /** * Gets a user's group. * @memberOf UserQuerySet * @instance * @param {Object} properties lookup properties used for path resolving * @returns {Promise} * @example {@lang javascript} * User.please().getGroup({user: 1, instanceName: 'test-one', group: 1}).then(function(group) {}); */ getGroup(properties = {}, group = {}) { const {Group} = this.getConfig(); this.properties = _.assign({}, this.properties, properties); return Group.please().getUserGroup(this.properties, group); }, /** * Adds a group to user. * @memberOf UserQuerySet * @instance * @param {Object} properties lookup properties used for path resolving * @param {Object} group object with id of group to be added * @returns {Promise} * @example {@lang javascript} * User.please().getGroup({user: 1, instanceName: 'test-one'}, {group: 1}).then(function(group) {}); */ addGroup(properties = {}, group = {}) { const {Group} = this.getConfig(); this.properties = _.assign({}, this.properties, properties); return Group.please().addUserGroup(this.properties, group); }, /** * Removes a user's group. * @memberOf UserQuerySet * @instance * @param {Object} properties lookup properties used for path resolving * @param {Object} group object with id of group to be added * @returns {Promise} * @example {@lang javascript} * User.please().deleteGroup({user: 1, instanceName: 'test-one'}, {group: 1}).then(function(group) {}); */ deleteGroup(properties = {}, group = {}) { const {Group} = this.getConfig(); this.properties = _.assign({}, this.properties, properties); return Group.please().deleteUserGroup(this.properties, group); }, getDetails(properties = {}, user = {}) { this.properties = _.assign({}, this.properties, properties, user); this.method = 'GET'; this.endpoint = 'groupUser'; return this.then((response) => { return this.model.fromJSON(response.user, this.properties); }); }, groupUsers(properties = {}) { this.properties = _.assign({}, this.properties, properties); this.method = 'GET'; this.endpoint = 'groupUsers'; return this.then((response) => { return this.model.please().asResultSet(response, 'user'); }); }, addUserToGroup(properties = {}, user = {}) { this.properties = _.assign({}, this.properties, properties); this.payload = user; this.method = 'POST'; this.endpoint = 'groupUsers'; return this.then((response) => { return this.model.fromJSON(response.user, this.properties); }); }, deleteUserFromGroup(properties = {}, user = {}) { this.properties = _.assign({}, this.properties, properties, user); this.payload = user; this.method = 'DELETE'; this.endpoint = 'groupUser'; return this; }, get(properties = {}) { const config = this.getConfig(); this.properties = _.assign({}, this.properties, properties); this.method = 'GET'; this.endpoint = 'detail'; if (_.isEmpty(config.getAccountKey()) && !_.isEmpty(config.getUserKey()) && !_.isEmpty(config.getApiKey())) { this.endpoint = 'user'; } return this; }, update(properties = {}, object = {}) { const config = this.getConfig(); this.properties = _.assign({}, this.properties, properties); this.payload = object; this.method = 'PATCH'; this.endpoint = 'detail'; if (_.isEmpty(config.getAccountKey()) && !_.isEmpty(config.getUserKey()) && !_.isEmpty(config.getApiKey())) { this.endpoint = 'user'; } return this; }, /** * Restes user key. * @memberOf UserQuerySet * @instance * @param {Object} properties lookup properties used for path resolving * @returns {Promise} * @example {@lang javascript} * User.please().resetKey({id: 1, instanceName: 'test-one'}).then(function(user) {}); */ resetKey(properties = {}) { this.properties = _.assign({}, this.properties, properties); this.method = 'POST'; this.endpoint = 'reset_key'; return this; }, /** * A convenience method for authenticating instance user with email and password. * @memberOf UserQuerySet * @instance * @param {Object} properties * @param {String} properties.instanceName * @param {Object} credentials * @param {String} credentials.email * @param {String} credentials.password * @returns {Promise} */ login(properties = {}, credentials = {}) { const config = this.getConfig(); this.properties = _.assign({}, this.properties, properties); this.method = 'POST'; this.endpoint = 'login'; this.payload = credentials; return this.then((response) => { config.setUserKey(response.user_key); return this.model.fromJSON(response, this.properties); }); }, /** * A convenience method for authenticating instance user with email and password. * @memberOf UserQuerySet * @instance * @param {Object} properties * @param {String} properties.instanceName * @param {String} properties.backend * @param {Object} credentials * @param {String} credentials.access_token * @returns {Promise} */ socialLogin(properties = {}, credentials = {}) { this.properties = _.assign({}, this.properties, properties); this.method = 'POST'; this.endpoint = 'socialLogin'; this.payload = credentials; return this; } }); const UserMeta = Meta({ name: 'user', pluralName: 'users', endpoints: { 'detail': { 'methods': ['delete', 'patch', 'put', 'get'], 'path': '/v1.1/instances/{instanceName}/users/{id}/' }, 'reset_key': { 'methods': ['post'], 'path': '/v1.1/instances/{instanceName}/users/{id}/reset_key/' }, 'list': { 'methods': ['post', 'get'], 'path': '/v1.1/instances/{instanceName}/users/' }, 'login': { 'methods': ['post'], 'path': '/v1.1/instances/{instanceName}/user/auth/' }, 'socialLogin': { 'methods': ['post'], 'path': '/v1.1/instances/{instanceName}/user/auth/{backend}/' }, 'user': { 'methods': ['get', 'post', 'patch'], 'path': '/v1.1/instances/{instanceName}/user/' }, 'groupUsers': { 'methods': ['get', 'post'], 'path': '/v1.1/instances/{instanceName}/groups/{id}/users/' }, 'groupUser': { 'methods': ['get', 'delete'], 'path': '/v1.1/instances/{instanceName}/groups/{id}/users/{user}/' } } }); const UserConstraints = { instanceName: { presence: true, length: { minimum: 5 } }, username: { presence: true, string: true }, password: { presence: true, string: true }, profile: { object: true }, 'profile.owner_permissions': { inclusion: ['none', 'read', 'write', 'full'] }, 'profile.group': { numericality: true }, 'profile.group_permissions': { inclusion: ['none', 'read', 'write', 'full'] }, 'profile.other_permissions': { inclusion: ['none', 'read', 'write', 'full'] }, 'profile.channel': { string: true }, 'profile.channel_room': { string: true } }; /** * OO wrapper around instance users {@link http://docs.syncano.com/v4.0/docs/user-management endpoint}. * @constructor * @type {User} * @property {Number} id * @property {String} instanceName * @property {String} username * @property {String} password * @property {String} user_key * @property {String} [links = {}] * @property {Date} [created_at = null] * @property {Date} [updated_at = null] */ const User = stampit() .compose(Model) .setMeta(UserMeta) .setQuerySet(UserQuerySet) .setConstraints(UserConstraints) .methods({ /** * Gets a user's groups. * @memberOf User * @instance * @returns {Promise} * @example {@lang javascript} * User.please().get({instanceName: 'test-one', id: 1}).then(function(user) { * user.getGroups().then(function(groups) {}); * }); */ getGroups() { const {Group} = this.getConfig(); return Group.please().getUserGroups({ user: this.id, instanceName: this.instanceName}); }, /** * Gets a user's group. * @memberOf User * @instance * @returns {Promise} * @example {@lang javascript} * User.please().get({instanceName: 'test-one', id: 1}).then(function(user) { * user.getGroup({ group: 1 }).then(function(group) {}); * }); */ getGroup(group = {}) { const {Group} = this.getConfig(); return Group.please().getUserGroup({ user: this.id, instanceName: this.instanceName}, group); }, /** * Adds a group to user. * @memberOf User * @instance * @param {Object} group object with id of group to be added * @returns {Promise} * @example {@lang javascript} * User.please().get({instanceName: 'test-one', id: 1}).then(function(user) { * user.addGroup({ group: 1}).then(function(group) {}); * }); */ addGroup(group = {}) { const {Group} = this.getConfig(); return Group.please().addUserGroup({ user: this.id, instanceName: this.instanceName}, group); }, /** * Removes a user's group. * @memberOf User * @instance * @param {Object} group object with id of group to be added * @returns {Promise} * @example {@lang javascript} * User.please().get({instanceName: 'test-one', id: 1}).then(function(user) { * user.deleteGroup({ group: 1}).then(function(group) {}); * }); */ deleteGroup(group = {}) { const {Group} = this.getConfig(); return Group.please().deleteUserGroup({ user: this.id, instanceName: this.instanceName}, group); }, /** * Restes user key. * @memberOf User * @instance * @returns {Promise} * @example {@lang javascript} * User.please().get({instanceName: 'test-one', id: 1}).then(function(user) { * user.resetKey().then(function(user) {}); * }); */ resetKey() { const meta = this.getMeta(); const path = meta.resolveEndpointPath('reset_key', this); return this.makeRequest('POST', path, {}).then((body) => this.serialize(body)); } }); export default User;