From 18f3af75cbf6bc29e28c1c4850c7c2c604f4f2bc Mon Sep 17 00:00:00 2001 From: OldHawk Date: Thu, 19 Oct 2017 18:44:22 +0800 Subject: [PATCH] feat(maker): admin oper can create maker group for user now, in user manager page --- config/env/torrents.js | 1 + modules/about/client/less/about.less | 35 +++- .../client/services/makers.client.service.js | 35 ++++ .../server/config/about.server.config.js | 14 ++ .../controllers/makers.server.controller.js | 154 ++++++++++++++++++ .../server/models/makers.server.model.js | 8 +- .../server/policies/about.server.policy.js | 58 +++++++ .../server/routes/about.server.routes.js | 22 +++ .../config/collections.server.config.js | 14 ++ modules/core/client/app/trans-string-en.js | 17 +- modules/core/client/app/trans-string-zh.js | 13 +- modules/core/client/less/mt.less | 9 + .../controllers/uploads.client.controller.js | 4 + .../views/uploads-torrents.client.view.html | 18 +- .../controllers/torrents.server.controller.js | 16 +- .../server/models/torrent.server.model.js | 4 + .../admin/user.client.controller.js | 51 +++++- .../views/admin/view-user.client.view.html | 34 +++- .../views/status/account.client.view.html | 6 + .../views/userinfo/userinfo.client.view.html | 6 + .../users/server/config/strategies/local.js | 1 + .../server/config/users.server.config.js | 8 +- .../controllers/admin.server.controller.js | 22 ++- .../users.authorization.server.controller.js | 21 ++- .../users/server/models/user.server.model.js | 5 + 25 files changed, 541 insertions(+), 35 deletions(-) create mode 100644 modules/about/client/services/makers.client.service.js create mode 100644 modules/about/server/config/about.server.config.js create mode 100644 modules/about/server/controllers/makers.server.controller.js create mode 100644 modules/about/server/policies/about.server.policy.js create mode 100644 modules/about/server/routes/about.server.routes.js create mode 100644 modules/collections/server/config/collections.server.config.js diff --git a/config/env/torrents.js b/config/env/torrents.js index e6aadb8a..30f72ec2 100644 --- a/config/env/torrents.js +++ b/config/env/torrents.js @@ -255,6 +255,7 @@ module.exports = { AdminTorrentSetSaleType: {name: 'AdminTorrentSetSaleType', enable: true}, AdminTorrentSetRecommendLevel: {name: 'AdminTorrentSetRecommendLevel', enable: true}, AdminTorrentSetReviewedStatus: {name: 'AdminTorrentSetReviewedStatus', enable: true}, + OperCreateMakerGroup: {name: 'OperCreateMakerGroup', enable: true}, userInvitationExchange: {name: 'userInvitationExchange', enable: true}, adminRemoveHnrWarning: {name: 'adminRemoveHnrWarning', enable: true}, diff --git a/modules/about/client/less/about.less b/modules/about/client/less/about.less index ff8566f1..bfb998a5 100644 --- a/modules/about/client/less/about.less +++ b/modules/about/client/less/about.less @@ -47,4 +47,37 @@ right: -20px; opacity: 0.5; } -} \ No newline at end of file +} + +.maker-side-overlay { + top: 50px !important; + @media (min-width: @screen-sm-min) { + width: 450px; + } + @media (max-width: @screen-xs-max) { + min-width: ~"calc(100% - 50px)"; + } + padding: 30px 15px; + .maker-form { + margin-top: 20px; + input { + width: 100%; + } + textarea { + margin-top: 20px; + width: 100%; + height: 150px; + } + } + .bottom-control { + background-color: #fdfdfd; + border-top: solid 1px #e6e6e6; + width: 100%; + height: 50px; + position: absolute; + left: 0; + bottom: 0; + padding: 8px 10px; + } + +} diff --git a/modules/about/client/services/makers.client.service.js b/modules/about/client/services/makers.client.service.js new file mode 100644 index 00000000..2bec208c --- /dev/null +++ b/modules/about/client/services/makers.client.service.js @@ -0,0 +1,35 @@ +(function () { + 'use strict'; + + angular + .module('about.services') + .factory('MakerGroupService', MakerGroupService); + + MakerGroupService.$inject = ['$resource']; + + function MakerGroupService($resource) { + return $resource('/api/makers/:makerId', { + forumId: '@_id' + }, { + update: { + method: 'PUT' + }, + save: { + method: 'POST', + url: '/api/makers/create/:userId', + params: { + userId: '@userId' + } + } + //, + //addModerator: { + // method: 'PUT', + // url: '/api/admin/forums/:forumId/addModerator/:username', + // params: { + // forumId: '@_id', + // username: '@_username' + // } + //} + }); + } +}()); diff --git a/modules/about/server/config/about.server.config.js b/modules/about/server/config/about.server.config.js new file mode 100644 index 00000000..629c3606 --- /dev/null +++ b/modules/about/server/config/about.server.config.js @@ -0,0 +1,14 @@ +'use strict'; + +/** + * Module dependencies + */ +var path = require('path'), + config = require(path.resolve('./config/config')); + +/** + * Module init function. + */ +module.exports = function (app, db) { + +}; diff --git a/modules/about/server/controllers/makers.server.controller.js b/modules/about/server/controllers/makers.server.controller.js new file mode 100644 index 00000000..c77a21c0 --- /dev/null +++ b/modules/about/server/controllers/makers.server.controller.js @@ -0,0 +1,154 @@ +'use strict'; + +/** + * Module dependencies + */ +var path = require('path'), + config = require(path.resolve('./config/config')), + mongoose = require('mongoose'), + Maker = mongoose.model('Maker'), + errorHandler = require(path.resolve('./modules/core/server/controllers/errors.server.controller')), + traceLogCreate = require(path.resolve('./config/lib/tracelog')).create; + +var traceConfig = config.meanTorrentConfig.trace; +var mtDebug = require(path.resolve('./config/lib/debug')); + +/** + * Create an maker + */ +exports.create = function (req, res) { + if (req.user.isOper) { + var user = req.model; + var maker = new Maker(req.body); + + maker.user = user._id; + maker.members.push(user._id); + + mtDebug.debugRed(maker); + + maker.save(function (err) { + if (err) { + return res.status(422).send({ + message: errorHandler.getErrorMessage(err) + }); + } else { + //save user`s maker + user.makers.push(maker); + user.save(function (err) { + if (err) { + return res.status(422).send({ + message: errorHandler.getErrorMessage(err) + }); + } else { + res.json(user); + } + }); + + //create trace log + traceLogCreate(req, traceConfig.action.OperCreateMakerGroup, { + user: user._id, + name: maker.name + }); + } + }); + } else { + return res.status(403).json({ + message: 'ERROR: User is not authorized' + }); + } +}; + +/** + * Show the current maker + */ +exports.read = function (req, res) { + // convert mongoose document to JSON + var maker = req.maker ? req.maker.toJSON() : {}; + + maker.isCurrentUserOwner = !!(req.user && maker.user && maker.user._id.toString() === req.user._id.toString()); + + res.json(maker); +}; + +/** + * Update an maker + */ +exports.update = function (req, res) { + var maker = req.maker; + + maker.name = req.body.name; + maker.desc = req.body.desc; + + maker.save(function (err) { + if (err) { + return res.status(422).send({ + message: errorHandler.getErrorMessage(err) + }); + } else { + res.json(maker); + } + }); +}; + +/** + * Delete an maker + */ +exports.delete = function (req, res) { + var maker = req.maker; + + maker.remove(function (err) { + if (err) { + return res.status(422).send({ + message: errorHandler.getErrorMessage(err) + }); + } else { + res.json(maker); + } + }); +}; + +/** + * List of makers + */ +exports.list = function (req, res) { + Maker.find() + .sort('-created') + .populate('user', 'username displayName profileImageURL isVip') + .populate('members', 'username displayName profileImageURL isVip') + .exec(function (err, makers) { + if (err) { + return res.status(422).send({ + message: errorHandler.getErrorMessage(err) + }); + } else { + res.json(makers); + } + }); +}; + +/** + * Maker middleware + */ +exports.makerByID = function (req, res, next, id) { + + if (!mongoose.Types.ObjectId.isValid(id)) { + return res.status(400).send({ + message: 'Maker is invalid' + }); + } + + Maker.findById(id) + .populate('user', 'username displayName profileImageURL isVip') + .populate('members', 'username displayName profileImageURL isVip') + .exec(function (err, maker) { + if (err) { + return next(err); + } else if (!maker) { + return res.status(404).send({ + message: 'No maker with that identifier has been found' + }); + } + req.maker = maker; + next(); + }); +}; diff --git a/modules/about/server/models/makers.server.model.js b/modules/about/server/models/makers.server.model.js index d3c2c95e..9d0dbb87 100644 --- a/modules/about/server/models/makers.server.model.js +++ b/modules/about/server/models/makers.server.model.js @@ -10,14 +10,14 @@ var mongoose = require('mongoose'), * Maker Schema */ var MakerSchema = new Schema({ - founder: { + user: { type: Schema.Types.ObjectId, ref: 'User' }, name: { type: String, unique: 'GROUP_NAME_ALREADY_EXISTS', - required: 'PLEASE_ENTER_GROUP_NAME', + uppercase: true, trim: true, default: '' }, @@ -30,6 +30,10 @@ var MakerSchema = new Schema({ type: Schema.Types.ObjectId, ref: 'User' }], + torrent_count: { + type: Number, + default: 0 + }, vote_average: { type: Number, default: 0 diff --git a/modules/about/server/policies/about.server.policy.js b/modules/about/server/policies/about.server.policy.js new file mode 100644 index 00000000..40d7a0b3 --- /dev/null +++ b/modules/about/server/policies/about.server.policy.js @@ -0,0 +1,58 @@ +'use strict'; + +/** + * Module dependencies + */ +var acl = require('acl'); + +// Using the memory backend +acl = new acl(new acl.memoryBackend()); + +/** + * Invoke Articles Permissions + */ +exports.invokeRolesPolicies = function () { + acl.allow([{ + roles: ['oper', 'admin'], + allows: [ + {resources: '/api/makers', permissions: '*'}, + {resources: '/api/makers/create/:userId', permissions: '*'}, + {resources: '/api/makers/:makerId', permissions: '*'} + ] + }, { + roles: ['user'], + allows: [ + {resources: '/api/makers', permissions: ['get']}, + {resources: '/api/makers/:makerId', permissions: ['get']} + ] + }]); +}; + +/** + * Check If Articles Policy Allows + */ +exports.isAllowed = function (req, res, next) { + var roles = (req.user) ? req.user.roles : ['guest']; + + // If an article is being processed and the current user created it then allow any manipulation + if (req.maker && req.user && req.maker.user && req.maker.user.id === req.user.id) { + return next(); + } + + // Check for user roles + acl.areAnyRolesAllowed(roles, req.route.path, req.method.toLowerCase(), function (err, isAllowed) { + if (err) { + // An authorization error occurred + return res.status(500).send('Unexpected authorization error'); + } else { + if (isAllowed) { + // Access granted! Invoke next middleware + return next(); + } else { + return res.status(403).json({ + message: 'User is not authorized' + }); + } + } + }); +}; diff --git a/modules/about/server/routes/about.server.routes.js b/modules/about/server/routes/about.server.routes.js new file mode 100644 index 00000000..7fcf7b59 --- /dev/null +++ b/modules/about/server/routes/about.server.routes.js @@ -0,0 +1,22 @@ +'use strict'; + +/** + * Module dependencies + */ +var aboutPolicy = require('../policies/about.server.policy'), + maker = require('../controllers/makers.server.controller'); + +module.exports = function (app) { + app.route('/api/makers').all(aboutPolicy.isAllowed) + .get(maker.list); + + app.route('/api/makers/create/:userId').all(aboutPolicy.isAllowed) + .post(maker.create); + + app.route('/api/makers/:makerId').all(aboutPolicy.isAllowed) + .get(maker.read) + .put(maker.update) + .delete(maker.delete); + + app.param('makerId', maker.makerByID); +}; diff --git a/modules/collections/server/config/collections.server.config.js b/modules/collections/server/config/collections.server.config.js new file mode 100644 index 00000000..629c3606 --- /dev/null +++ b/modules/collections/server/config/collections.server.config.js @@ -0,0 +1,14 @@ +'use strict'; + +/** + * Module dependencies + */ +var path = require('path'), + config = require(path.resolve('./config/config')); + +/** + * Module init function. + */ +module.exports = function (app, db) { + +}; diff --git a/modules/core/client/app/trans-string-en.js b/modules/core/client/app/trans-string-en.js index f79af925..c7abf846 100644 --- a/modules/core/client/app/trans-string-en.js +++ b/modules/core/client/app/trans-string-en.js @@ -379,7 +379,9 @@ SELECT_SE: '4.1. Please select number of seasons and input number of episodes', SELECT_TAGS: '5. Please select any tags for the resources', ENTER_VIDEO_NFO: '6. Please enter video and audio NFO', - TORRENTS_SUBMIT_UPLOAD: '7. Agree the rules and submit your resources', + SELECT_MAKER_GROUP: '7. Please select torrent maker group upload from', + MAKER_NULL: 'NULL', + TORRENTS_SUBMIT_UPLOAD: '8. Agree the rules and submit your resources', SUBMIT_BUTTON: 'OK, SUBMIT NOW', CANCEL_BUTTON: 'NO, CANCEL IT', AGREE_RULES: 'I agree and already read all the rules, read here', @@ -463,7 +465,12 @@ ABOUT: { CLIENT_BLACK_LIST: 'Client Black List', MAKER_GROUP: 'Torrents Maker Group', - BLACK_TOOLTIP: '

Note:

All the clients in the list was forbidden by server and can not announce or get any torrent data, For more help, please contact our administrator.' + BLACK_TOOLTIP: '

Note:

All the clients in the list was forbidden by server and can not announce or get any torrent data, For more help, please contact our administrator.', + FORM_MAKER_NAME: 'Maker Group Name', + FORM_MAKER_DESC: 'Maker Group Description', + FORM_MAKER_FOR: 'Create maker group for - {{name}}', + MAKER_CREATE_SUCCESSFULLY: 'Create maker group successfully', + MAKER_CREATE_FAILED: 'Create maker group failed' }, //collections views @@ -525,9 +532,11 @@ STATUS: 'Status', NORMAL: 'normal', BANNED: 'banned', - BTN_BAN: 'ban', - BTN_UNBAN: 'unban', + BTN_BAN: 'Ban', + BTN_UNBAN: 'Unban', + BTN_CREATE_MAKER: 'Create Maker', SEALED: 'sealed', + MAKER: 'Maker Group', VIP_START_AT: 'Vip start at', VIP_END_AT: 'Vip end at', UPLOADED: 'Total uploaded', diff --git a/modules/core/client/app/trans-string-zh.js b/modules/core/client/app/trans-string-zh.js index e77554f6..ee15fd87 100644 --- a/modules/core/client/app/trans-string-zh.js +++ b/modules/core/client/app/trans-string-zh.js @@ -379,7 +379,9 @@ SELECT_SE: '4.1. 请选择电视剧季数并输入本资源为本剧第几集', SELECT_TAGS: '5. 请为资源选择合适的标签', ENTER_VIDEO_NFO: '6. 请输入视频和音频的NFO信息', - TORRENTS_SUBMIT_UPLOAD: '7. 同意上传协议,并提交', + SELECT_MAKER_GROUP: '7. 请选择你上传时使用的资源压制小组', + MAKER_NULL: '无', + TORRENTS_SUBMIT_UPLOAD: '8. 同意上传协议,并提交', SUBMIT_BUTTON: '已备妥,现在提交', CANCEL_BUTTON: '算了,以后再说', AGREE_RULES: '我已阅读并同意站内所有协议条款,协议条款', @@ -463,7 +465,12 @@ ABOUT: { CLIENT_BLACK_LIST: '禁止客户端列表', MAKER_GROUP: '资源压制小组', - BLACK_TOOLTIP: '

提示:

下面列出的所有客户端都已被服务器禁止,使用它们将不能下载到任何数据, 如需其它帮助,请与我们的 系统管理员 联系.' + BLACK_TOOLTIP: '

提示:

下面列出的所有客户端都已被服务器禁止,使用它们将不能下载到任何数据, 如需其它帮助,请与我们的 系统管理员 联系.', + FORM_MAKER_NAME: '资源压制小组名称', + FORM_MAKER_DESC: '资源压制小组简介', + FORM_MAKER_FOR: '创建资源压制小组 - {{name}}', + MAKER_CREATE_SUCCESSFULLY: '资源压制小组创建成功', + MAKER_CREATE_FAILED: '资源压制小组创建失败' }, //collections views @@ -527,7 +534,9 @@ BANNED: '被禁止', BTN_BAN: '禁止', BTN_UNBAN: '解禁', + BTN_CREATE_MAKER: '创建小组', SEALED: '冻结', + MAKER: '资源压制小组', VIP_START_AT: 'Vip 资格开始于', VIP_END_AT: 'Vip 资格结束于', UPLOADED: '总上传量', diff --git a/modules/core/client/less/mt.less b/modules/core/client/less/mt.less index 36769aa3..0e9b39f5 100644 --- a/modules/core/client/less/mt.less +++ b/modules/core/client/less/mt.less @@ -1434,6 +1434,15 @@ body { } } +.maker-list { + &:not(:first-child) { + &::before { + content: " | "; + font-weight: bold; + } + } +} + .set-score-popover { max-width: 250px; max-height: 150px; diff --git a/modules/torrents/client/controllers/uploads.client.controller.js b/modules/torrents/client/controllers/uploads.client.controller.js index b52b9d58..8fe3a3c4 100644 --- a/modules/torrents/client/controllers/uploads.client.controller.js +++ b/modules/torrents/client/controllers/uploads.client.controller.js @@ -21,6 +21,7 @@ vm.progress = 0; vm.torrentInfo = null; vm.tags = []; + vm.maker = 'NULL'; vm.videoNfo = ''; vm.customTorrent = {}; @@ -351,6 +352,7 @@ var torrent = new TorrentsService({ info_hash: vm.torrentInfo.info_hash, + maker: vm.maker === 'NULL' ? undefined : vm.maker, torrent_filename: vm.torrentInfo.filename, torrent_type: 'movie', torrent_tags: t, @@ -390,6 +392,7 @@ var torrent = new TorrentsService({ info_hash: vm.torrentInfo.info_hash, + maker: vm.maker === 'NULL' ? undefined : vm.maker, torrent_filename: vm.torrentInfo.filename, torrent_type: 'tvserial', torrent_seasons: vm.selectedSeasons, @@ -450,6 +453,7 @@ var torrent = new TorrentsService({ info_hash: vm.torrentInfo.info_hash, + maker: vm.maker === 'NULL' ? undefined : vm.maker, torrent_filename: vm.torrentInfo.filename, torrent_type: vm.selectedType, torrent_tags: t, diff --git a/modules/torrents/client/views/uploads-torrents.client.view.html b/modules/torrents/client/views/uploads-torrents.client.view.html index b8ef95fd..ff3ff322 100644 --- a/modules/torrents/client/views/uploads-torrents.client.view.html +++ b/modules/torrents/client/views/uploads-torrents.client.view.html @@ -55,7 +55,23 @@
-
+
+ +
+ + +
+
+ +
+
+

+
+ + + +
+ +
+ + +
+
+