mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +08:00
remove domain system
This commit is contained in:
1 parent
7fa4a58abe
commit
fc26af30ef
31 files changed
+709
-1242
No files matched your search
+152
-22
@@ -1,6 +1,4 @@
|
||||
const
|
||||
perm = require('../permission'),
|
||||
priv = require('../privilege');
|
||||
const perm = require('../permission');
|
||||
const BUILTIN_USERS = [
|
||||
{
|
||||
_id: 0,
|
||||
@@ -11,12 +9,12 @@ const BUILTIN_USERS = [
|
||||
salt: '',
|
||||
hash: '',
|
||||
gender: 'other',
|
||||
regat: new Date(0),
|
||||
regat: new Date(),
|
||||
regip: '127.0.0.1',
|
||||
priv: priv.PRIV_NONE,
|
||||
gravatar: '',
|
||||
loginat: new Date(),
|
||||
loginip: '127.0.0.1'
|
||||
loginip: '127.0.0.1',
|
||||
role: 'guest'
|
||||
},
|
||||
{
|
||||
_id: 1,
|
||||
@@ -30,23 +28,155 @@ const BUILTIN_USERS = [
|
||||
regip: '127.0.0.1',
|
||||
loginat: new Date(),
|
||||
loginip: '127.0.0.1',
|
||||
priv: priv.PRIV_DEFAULT,
|
||||
gravatar: 'guest@hydro'
|
||||
gravatar: 'guest@hydro',
|
||||
role: 'guest'
|
||||
}
|
||||
];
|
||||
const BUILTIN_DOMAINS = [{
|
||||
_id: 'system',
|
||||
owner: 0,
|
||||
roles: {
|
||||
guest: perm.PERM_BASIC,
|
||||
default: perm.PERM_DEFAULT,
|
||||
member: perm.PERM_DEFAULT,
|
||||
admin: perm.PERM_ADMIN
|
||||
},
|
||||
gravatar: '',
|
||||
name: 'System',
|
||||
bulletin: ''
|
||||
}];
|
||||
const BUILTIN_ROLES = [
|
||||
{ _id: 'guest', perm: perm.PERM_BASIC },
|
||||
{ _id: 'default', perm: perm.PERM_DEFAULT },
|
||||
{ _id: 'admin', perm: perm.PERM_ADMIN }
|
||||
];
|
||||
const CATEGORIES = {
|
||||
'动态规划': [
|
||||
'LCS',
|
||||
'LIS',
|
||||
'背包',
|
||||
'单调性DP',
|
||||
'环形DP',
|
||||
'树形DP',
|
||||
'状态压缩DP'
|
||||
],
|
||||
'搜索': [
|
||||
'枚举',
|
||||
'搜索与剪枝',
|
||||
'启发式搜索',
|
||||
'DLX',
|
||||
'双向搜索',
|
||||
'折半搜索',
|
||||
'记忆化搜索',
|
||||
'模拟退火'
|
||||
],
|
||||
'计算几何': [
|
||||
'半平面交',
|
||||
'凸包',
|
||||
'几何图形的交与并',
|
||||
'旋转卡壳',
|
||||
'点定位',
|
||||
'坐标变换',
|
||||
'离散化与扫描',
|
||||
'反演',
|
||||
'Voronoi图',
|
||||
'平面图的对偶图',
|
||||
'三角剖分',
|
||||
'梯形剖分',
|
||||
'几何知识'
|
||||
],
|
||||
'贪心': [],
|
||||
'树结构': [
|
||||
'最近公共祖先',
|
||||
'生成树',
|
||||
'DFS序列',
|
||||
'树上倍增',
|
||||
'树的分治',
|
||||
'树链剖分',
|
||||
'Link-Cut-Tree'
|
||||
],
|
||||
'图结构': [
|
||||
'平面图',
|
||||
'二分图',
|
||||
'二分图匹配',
|
||||
'最短路',
|
||||
'差分约束',
|
||||
'拓扑排序',
|
||||
'网络流',
|
||||
'强连通分量',
|
||||
'割点割边',
|
||||
'欧拉回路',
|
||||
'2-SAT'
|
||||
],
|
||||
'数论': [
|
||||
'素数判定',
|
||||
'欧几里得算法',
|
||||
'不定方程',
|
||||
'数位统计',
|
||||
'解线性同余方程',
|
||||
'baby-step-giant-step',
|
||||
'Pell方程',
|
||||
'大整数质因数分解',
|
||||
'勾股方程',
|
||||
'积性函数',
|
||||
'Fibonacci数列'
|
||||
],
|
||||
'模拟': [],
|
||||
'数据结构': [
|
||||
'栈',
|
||||
'队列',
|
||||
'链表',
|
||||
'单调队列',
|
||||
'并查集',
|
||||
'堆',
|
||||
'平衡树',
|
||||
'线段树',
|
||||
'树状数组',
|
||||
'树套树',
|
||||
'四分树',
|
||||
'划分树',
|
||||
'归并树',
|
||||
'k-d树',
|
||||
'块状链表',
|
||||
'Hashing',
|
||||
'函数式编程'
|
||||
],
|
||||
'博弈论': [],
|
||||
'字符串': [
|
||||
'KMP',
|
||||
'后缀数据结构',
|
||||
'Trie树',
|
||||
'AC自动机',
|
||||
'Manacher',
|
||||
'表达式处理',
|
||||
'最小表示法'
|
||||
],
|
||||
'组合数学': [
|
||||
'生成函数',
|
||||
'容斥原理',
|
||||
'康托展开',
|
||||
'Catalan数列',
|
||||
'Stirling数',
|
||||
'差分',
|
||||
'Polya定理'
|
||||
],
|
||||
'线性代数': [
|
||||
'矩阵乘法',
|
||||
'高斯消元',
|
||||
'线性规划'
|
||||
],
|
||||
'高精度': [
|
||||
'FFT'
|
||||
],
|
||||
'递推': [],
|
||||
'概率论': [
|
||||
'随机化'
|
||||
],
|
||||
'NPC': [],
|
||||
'其他': [
|
||||
'二分查找',
|
||||
'三分查找',
|
||||
'双指针扫描',
|
||||
'分治',
|
||||
'分块',
|
||||
'RMQ',
|
||||
'快速幂',
|
||||
'数学',
|
||||
'排序',
|
||||
'构造'
|
||||
]
|
||||
};
|
||||
const FOOTER_EXTRA_HTMLS = [];
|
||||
const VIEW_LANGS = [
|
||||
{ code: 'zh-CN', name: 'zh-CN' }
|
||||
];
|
||||
module.exports = {
|
||||
BUILTIN_USERS, BUILTIN_DOMAINS
|
||||
BUILTIN_USERS, BUILTIN_ROLES, CATEGORIES, VIEW_LANGS, FOOTER_EXTRA_HTMLS
|
||||
};
|
||||
+14
-15
@@ -1,5 +1,4 @@
|
||||
const
|
||||
domain = require('./domain'),
|
||||
validator = require('../lib/validator'),
|
||||
{ ValidationError, ContestNotFoundError } = require('../error'),
|
||||
RULE_HOMEWORK = require('../module/contest/homework'),
|
||||
@@ -18,37 +17,37 @@ const RULES = {
|
||||
|
||||
module.exports = {
|
||||
RULES,
|
||||
async add(domainId, title, content, owner, rule,
|
||||
async add(title, content, owner, rule,
|
||||
beginAt = new Date(), endAt = new Date(), pids = [], data) {
|
||||
validator.checkTitle(title);
|
||||
validator.checkContent(content);
|
||||
if (!this.RULES[rule]) throw new ValidationError('rule');
|
||||
if (beginAt >= endAt) throw new ValidationError('beginAt', 'endAt');
|
||||
Object.assign(data, { domainId, content, owner, title, rule, beginAt, endAt, pids, attend: 0 });
|
||||
Object.assign(data, { content, owner, title, rule, beginAt, endAt, pids, attend: 0 });
|
||||
this.RULES[rule].check(data);
|
||||
return await coll.insertOne(data);
|
||||
},
|
||||
count: query => coll.find(query).count(),
|
||||
async edit(domainId, cid, $set) {
|
||||
async edit(cid, $set) {
|
||||
if ($set.title) validator.checkTitle($set.title);
|
||||
if ($set.content) validator.checkIntro($set.content);
|
||||
if ($set.rule)
|
||||
if (!this.RULES[$set.rule]) throw new ValidationError('rule');
|
||||
if ($set.beginAt && $set.endAt)
|
||||
if ($set.beginAt >= $set.endAt) throw new ValidationError('beginAt', 'endAt');
|
||||
let cdoc = await coll.findOne({ domainId, cid });
|
||||
if (!cdoc) throw new ContestNotFoundError(domainId, cid);
|
||||
let cdoc = await coll.findOne({ cid });
|
||||
if (!cdoc) throw new ContestNotFoundError(cid);
|
||||
this.RULES[$set.rule || cdoc.rule].check(Object.assign(cdoc, $set));
|
||||
await coll.findOneAndUpdate({ domainId, cid }, { $set });
|
||||
await coll.findOneAndUpdate({ cid }, { $set });
|
||||
return cdoc;
|
||||
},
|
||||
async get(domainId, cid) {
|
||||
let tdoc = await coll.findOne({ domainId, cid });
|
||||
if (!tdoc) throw new ContestNotFoundError(domainId, cid);
|
||||
async get( cid) {
|
||||
let tdoc = await coll.findOne({ cid });
|
||||
if (!tdoc) throw new ContestNotFoundError(cid);
|
||||
return tdoc;
|
||||
},
|
||||
get_multi: (domainId, query, fields) => coll.find(Object.assign({ domainId }, query), { fields }),
|
||||
get_multi_status: (query, fields) => coll.find(query, { fields }),
|
||||
get_multi: (query, fields) => coll.find(query, { fields }),
|
||||
get_multi_status: (query, fields) => coll_status.find(query, { fields }),
|
||||
async get_random_id(query) {
|
||||
let pdocs = coll.find(query);
|
||||
let pcount = await pdocs.count();
|
||||
@@ -57,8 +56,8 @@ module.exports = {
|
||||
return pdoc.pid;
|
||||
} else return null;
|
||||
},
|
||||
get_status: (domainId, cid, uid, fields) => coll_status.findOne({ domainId, cid, uid }, { fields }),
|
||||
set_status: (domainId, cid, uid, $set) => coll_status.findOneAndUpdate({ domainId, cid, uid }, { $set })
|
||||
get_status: (cid, uid, fields) => coll_status.findOne({ cid, uid }, { fields }),
|
||||
set_status: (cid, uid, $set) => coll_status.findOneAndUpdate({ cid, uid }, { $set })
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -321,7 +320,7 @@ class ContestCommonOperationMixin(object):
|
||||
fields={'doc_id': 1}) \
|
||||
.sort('doc_id', 1) \
|
||||
.to_list()
|
||||
exist_pids = [pdoc['doc_id'] for pdoc in pdocs]
|
||||
exist_pids = [pdoc['_id'] for pdoc in pdocs]
|
||||
if len(pids) != len(exist_pids):
|
||||
for pid in pids:
|
||||
if pid not in exist_pids:
|
||||
|
||||
@@ -1,315 +0,0 @@
|
||||
const
|
||||
validator = require('../utils').validator,
|
||||
user = require('./user'),
|
||||
{ DomainAlreadyExistError, DomainNotFoundError } = require('../error'),
|
||||
db = require('../service/db.js'),
|
||||
coll = db.collection('domain');
|
||||
|
||||
module.exports = {
|
||||
/**
|
||||
* @param {string} domainId
|
||||
* @param {int} owner
|
||||
* @param {roles} roles
|
||||
* @param {str} name
|
||||
* @param {str} gravatar
|
||||
* @param {str} bulletin
|
||||
*/
|
||||
async add(domainId, owner, roles, name, gravatar, bulletin = '') {
|
||||
validator.checkDomainId(domainId);
|
||||
validator.checkName(name);
|
||||
validator.checkBulletin(bulletin);
|
||||
try {
|
||||
let result = await coll.insertOne({
|
||||
_id: domainId, pending: true, owner, roles, name, gravatar, bulletin
|
||||
});
|
||||
domainId = result.insertedId;
|
||||
} catch (e) {
|
||||
throw new DomainAlreadyExistError(domainId);
|
||||
}
|
||||
await (await user.getById(owner, domainId)).joinDomain('root');
|
||||
await coll.updateOne({ _id: domainId }, { $unset: { pending: '' } });
|
||||
return domainId;
|
||||
},
|
||||
/**
|
||||
* @param {string} domainId
|
||||
* @param {object} fields
|
||||
*/
|
||||
async get(domainId, fields) {
|
||||
let ddoc = await coll.findOne({ _id: domainId }, fields);
|
||||
if (!ddoc) throw new DomainNotFoundError(domainId);
|
||||
return ddoc;
|
||||
},
|
||||
/**
|
||||
* Increments the problem ID counter.
|
||||
* @param {string} domainId
|
||||
* @returns {number} Integer value before increment.
|
||||
*/
|
||||
async incPidCounter(domainId) {
|
||||
await coll.updateOne({ _id: domainId, pidCounter: { $exists: false } },
|
||||
{ $set: { pidCounter: 1000 } });
|
||||
let doc = await coll.findOneAndUpdate({ _id: domainId }, { $inc: { pidCounter: 1 } });
|
||||
return doc.value.pidCounter;
|
||||
},
|
||||
async incUser(domainId, uid, $inc) {
|
||||
let res = await coll.findOneAndUpdate({ domainId, uid }, { $inc }, { upsert: true });
|
||||
return res.value;
|
||||
}
|
||||
};
|
||||
/*
|
||||
|
||||
async def add_continue(domainId: str, ensure_owner_uid: int=None):
|
||||
ddoc = await get(domainId)
|
||||
if 'pending' not in ddoc:
|
||||
raise error.DomainNotFoundError(domainId)
|
||||
owner_uid = ddoc['owner_uid']
|
||||
if ensure_owner_uid != None and owner_uid != ensure_owner_uid:
|
||||
raise error.DomainNotFoundError(domainId)
|
||||
try:
|
||||
await add_user_role(domainId, owner_uid, builtin.ROLE_ROOT)
|
||||
except error.UserAlreadyDomainMemberError:
|
||||
pass
|
||||
coll = db.coll('domain')
|
||||
await coll.update_one({'_id': domainId},
|
||||
{'$unset': {'pending': ''}})
|
||||
|
||||
def get_multi(*, fields=None, **kwargs):
|
||||
coll = db.coll('domain')
|
||||
return coll.find(kwargs, fields)
|
||||
|
||||
|
||||
@argmethod.wrap
|
||||
async def get_list(*, fields=None, limit: int=None, **kwargs):
|
||||
coll = db.coll('domain')
|
||||
return await coll.find(kwargs, fields).limit(limit).to_list(None)
|
||||
|
||||
|
||||
def get_pending(**kwargs):
|
||||
return get_multi(pending=True, **kwargs)
|
||||
|
||||
|
||||
@argmethod.wrap
|
||||
async def edit(domainId: str, **kwargs):
|
||||
for domain in builtin.DOMAINS:
|
||||
if domain['_id'] == domainId:
|
||||
raise error.BuiltinDomainError(domainId)
|
||||
coll = db.coll('domain')
|
||||
if 'owner_uid' in kwargs:
|
||||
del kwargs['owner_uid']
|
||||
if 'name' in kwargs:
|
||||
validator.check_name(kwargs['name'])
|
||||
# TODO(twd2): check kwargs
|
||||
return await coll.find_one_and_update(filter={'_id': domainId},
|
||||
update={'$set': {**kwargs}},
|
||||
return_document=ReturnDocument.AFTER)
|
||||
|
||||
|
||||
async def unset(domainId, fields):
|
||||
# TODO(twd2): check fields
|
||||
coll = db.coll('domain')
|
||||
return await coll.find_one_and_update(filter={'_id': domainId},
|
||||
update={'$unset': dict((f, '') for f in set(fields))},
|
||||
return_document=ReturnDocument.AFTER)
|
||||
|
||||
|
||||
@argmethod.wrap
|
||||
async def set_role(domainId: str, role: str, perm: int):
|
||||
return await set_roles(domainId, {role: perm})
|
||||
|
||||
|
||||
@argmethod.wrap
|
||||
async def set_roles(domainId: str, roles):
|
||||
roles = {str(role): int(perm) for role, perm in roles.items()}
|
||||
update = {}
|
||||
for role in roles:
|
||||
validator.check_role(role)
|
||||
if role in builtin.BUILTIN_ROLE_DESCRIPTORS:
|
||||
if not builtin.BUILTIN_ROLE_DESCRIPTORS[role].modifiable:
|
||||
raise error.ModifyBuiltinRoleError(domainId, role)
|
||||
update['roles.{0}'.format(role)] = roles[role]
|
||||
for domain in builtin.DOMAINS:
|
||||
if domain['_id'] == domainId:
|
||||
raise error.BuiltinDomainError(domainId)
|
||||
coll = db.coll('domain')
|
||||
return await coll.find_one_and_update(filter={'_id': domainId},
|
||||
update={'$set': update},
|
||||
return_document=ReturnDocument.AFTER)
|
||||
|
||||
|
||||
@argmethod.wrap
|
||||
async def delete_role(domainId: str, role: str):
|
||||
return await delete_roles(domainId, [role])
|
||||
|
||||
|
||||
async def delete_roles(domainId: str, roles):
|
||||
roles = list(set(roles))
|
||||
for role in roles:
|
||||
validator.check_role(role)
|
||||
if role in builtin.BUILTIN_ROLE_DESCRIPTORS:
|
||||
raise error.ModifyBuiltinRoleError(domainId, role)
|
||||
for domain in builtin.DOMAINS:
|
||||
if domain['_id'] == domainId:
|
||||
raise error.BuiltinDomainError(domainId)
|
||||
user_coll = db.coll('domain.user')
|
||||
await user_coll.update_many({'domainId': domainId, 'role': {'$in': list(roles)}},
|
||||
{'$unset': {'role': ''}})
|
||||
coll = db.coll('domain')
|
||||
return await coll.find_one_and_update(filter={'_id': domainId},
|
||||
update={'$unset': dict(('roles.{0}'.format(role), '')
|
||||
for role in roles)},
|
||||
return_document=ReturnDocument.AFTER)
|
||||
|
||||
|
||||
@argmethod.wrap
|
||||
async def transfer(domainId: str, old_owner_uid: int, new_owner_uid: int):
|
||||
for domain in builtin.DOMAINS:
|
||||
if domain['_id'] == domainId:
|
||||
raise error.BuiltinDomainError(domainId)
|
||||
coll = db.coll('domain')
|
||||
return await coll.find_one_and_update(filter={'_id': domainId, 'owner_uid': old_owner_uid},
|
||||
update={'$set': {'owner_uid': new_owner_uid}},
|
||||
return_document=ReturnDocument.AFTER)
|
||||
|
||||
|
||||
async def set_user(domainId, uid, **kwargs):
|
||||
coll = db.coll('domain.user')
|
||||
return await coll.find_one_and_update(filter={'domainId': domainId, 'uid': uid},
|
||||
update={'$set': kwargs},
|
||||
upsert=True,
|
||||
return_document=ReturnDocument.AFTER)
|
||||
|
||||
|
||||
async def unset_user(domainId, uid, fields):
|
||||
coll = db.coll('domain.user')
|
||||
return await coll.find_one_and_update(filter={'domainId': domainId, 'uid': uid},
|
||||
update={'$unset': dict((f, '') for f in set(fields))},
|
||||
upsert=True,
|
||||
return_document=ReturnDocument.AFTER)
|
||||
|
||||
|
||||
async def set_users(domainId, uids, **kwargs):
|
||||
coll = db.coll('domain.user')
|
||||
await coll.update_many({'domainId': domainId, 'uid': {'$in': list(set(uids))}},
|
||||
{'$set': kwargs},
|
||||
upsert=False)
|
||||
|
||||
|
||||
async def unset_users(domainId, uids, fields):
|
||||
coll = db.coll('domain.user')
|
||||
await coll.update_many({'domainId': domainId, 'uid': {'$in': list(set(uids))}},
|
||||
{'$unset': dict((f, '') for f in set(fields))},
|
||||
upsert=True)
|
||||
|
||||
|
||||
|
||||
@argmethod.wrap
|
||||
async def set_user_role(domainId: str, uid: int, role: str):
|
||||
validator.check_role(role)
|
||||
# use set_users to utilize "upsert=False"
|
||||
return await set_users(domainId, [uid], role=role)
|
||||
|
||||
|
||||
@argmethod.wrap
|
||||
async def unset_user_role(domainId: str, uid: int):
|
||||
return await unset_user(domainId, uid, ['role'])
|
||||
|
||||
|
||||
async def set_users_role(domainId: str, uids, role: str):
|
||||
validator.check_role(role)
|
||||
await set_users(domainId, uids, role=role)
|
||||
|
||||
|
||||
async def unset_users_role(domainId: str, uids):
|
||||
await unset_users(domainId, uids, ['role'])
|
||||
|
||||
|
||||
async def inc_user_usage(domainId: str, uid: int, usage_field: str, usage: int, quota: int):
|
||||
coll = db.coll('domain.user')
|
||||
try:
|
||||
return await coll.find_one_and_update(filter={'domainId': domainId, 'uid': uid,
|
||||
usage_field: {'$not': {'$gte': quota - usage}}},
|
||||
update={'$inc': {usage_field: usage}},
|
||||
upsert=True,
|
||||
return_document=ReturnDocument.AFTER)
|
||||
except errors.DuplicateKeyError:
|
||||
raise error.UsageExceededError(domainId, uid, usage_field, usage, quota)
|
||||
|
||||
|
||||
def get_multi_user(*, fields=None, **kwargs):
|
||||
coll = db.coll('domain.user')
|
||||
return coll.find(kwargs, fields)
|
||||
|
||||
|
||||
async def get_dict_user_by_uid(domainId, uids, *, fields=None):
|
||||
result = dict()
|
||||
async for dudoc in get_multi_user(
|
||||
domainId=domainId, uid={'$in': list(set(uids))}, fields=fields):
|
||||
result[dudoc['uid']] = dudoc
|
||||
return result
|
||||
|
||||
|
||||
async def get_dict_user_by_domainId(uid, *, fields=None):
|
||||
result = dict()
|
||||
async for dudoc in get_multi_user(uid=uid, fields=fields):
|
||||
result[dudoc['domainId']] = dudoc
|
||||
return result
|
||||
|
||||
|
||||
def get_all_roles(ddoc):
|
||||
builtin_roles = {role: rd.default_permission for role, rd in builtin.BUILTIN_ROLE_DESCRIPTORS.items()}
|
||||
domain_roles = ddoc['roles']
|
||||
return {**builtin_roles, **domain_roles}
|
||||
|
||||
|
||||
def get_join_settings(ddoc, now):
|
||||
if 'join' not in ddoc:
|
||||
return None
|
||||
join_settings = ddoc['join']
|
||||
if not join_settings:
|
||||
return None
|
||||
if join_settings['method'] == constant.domain.JOIN_METHOD_NONE:
|
||||
return None
|
||||
if join_settings['role'] not in ddoc['roles']:
|
||||
return None
|
||||
if join_settings['expire'] != None and join_settings['expire'] < now:
|
||||
return None
|
||||
return join_settings
|
||||
|
||||
|
||||
@argmethod.wrap
|
||||
async def get_prefix_search(prefix: str, fields={}, limit: int=50):
|
||||
prefix_lower = prefix.lower()
|
||||
builtin_ddocs = []
|
||||
for domain in builtin.DOMAINS:
|
||||
if domain['_id'].lower().startswith(prefix_lower) or \
|
||||
domain['name'].lower().startswith(prefix_lower):
|
||||
builtin_ddocs.append(domain)
|
||||
regex = r'\A\Q{0}\E'.format(prefix.replace(r'\E', r'\E\\E\Q'))
|
||||
coll = db.coll('domain')
|
||||
ddocs = await coll.find({'$or': [{'_id': {'$regex': regex}},
|
||||
{'name': {'$regex': regex}}]},
|
||||
projection=fields) \
|
||||
.limit(limit) \
|
||||
.to_list()
|
||||
return builtin_ddocs + ddocs
|
||||
|
||||
|
||||
@argmethod.wrap
|
||||
async def ensure_indexes():
|
||||
coll = db.coll('domain')
|
||||
await coll.create_index('owner_uid')
|
||||
await coll.create_index('name')
|
||||
user_coll = db.coll('domain.user')
|
||||
await user_coll.create_index('uid')
|
||||
await user_coll.create_index([('domainId', 1),
|
||||
('uid', 1)], unique=True)
|
||||
await user_coll.create_index([('domainId', 1),
|
||||
('role', 1)], sparse=True)
|
||||
await user_coll.create_index([('domainId', 1),
|
||||
('rp', -1)])
|
||||
await user_coll.create_index([('domainId', 1),
|
||||
('rank', 1)])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
argmethod.invoke_by_args()
|
||||
*/
|
||||
+8
-11
@@ -6,7 +6,6 @@ const
|
||||
coll_status = db.collection('problem.status');
|
||||
|
||||
/**
|
||||
* @param {string} domainId
|
||||
* @param {string} title
|
||||
* @param {string} content
|
||||
* @param {number} owner
|
||||
@@ -17,7 +16,6 @@ const
|
||||
* @param {boolean} hidden
|
||||
*/
|
||||
async function add({
|
||||
domainId,
|
||||
title,
|
||||
content,
|
||||
owner,
|
||||
@@ -30,7 +28,6 @@ async function add({
|
||||
validator.checkTitle(title);
|
||||
validator.checkContent(content);
|
||||
await coll.insertOne({
|
||||
domainId,
|
||||
content,
|
||||
owner,
|
||||
pid,
|
||||
@@ -44,24 +41,24 @@ async function add({
|
||||
});
|
||||
return pid;
|
||||
}
|
||||
async function get({ domainId, pid, uid }) {
|
||||
async function get({ pid, uid }) {
|
||||
pid = parseInt(pid) || pid;
|
||||
let pdoc = await coll.findOne({ domainId, pid });
|
||||
if (!pdoc) throw new ProblemNotFoundError(domainId, pid);
|
||||
let pdoc = await coll.findOne({ pid });
|
||||
if (!pdoc) throw new ProblemNotFoundError(pid);
|
||||
pdoc.psdoc = uid ?
|
||||
await coll_status.findOne({ domainId, pid, uid }) :
|
||||
await coll_status.findOne({ pid, uid }) :
|
||||
null;
|
||||
return pdoc;
|
||||
}
|
||||
async function getMany(query, sort, page, limit) {
|
||||
return await coll.find(query).sort(sort).skip((page - 1) * limit).limit(limit).toArray();
|
||||
}
|
||||
async function edit(domainId, pid, $set) {
|
||||
async function edit(pid, $set) {
|
||||
if ($set.title) validator.checkTitle($set.title);
|
||||
if ($set.content) validator.checkContent($set.content);
|
||||
await coll.findOneAndUpdate({ domainId, pid }, { $set });
|
||||
let pdoc = await coll.findOne({ domainId, pid });
|
||||
if (!pdoc) throw new ProblemNotFoundError(domainId, pid);
|
||||
await coll.findOneAndUpdate({ pid }, { $set });
|
||||
let pdoc = await coll.findOne({ pid });
|
||||
if (!pdoc) throw new ProblemNotFoundError(pid);
|
||||
return pdoc;
|
||||
}
|
||||
async function count(query) {
|
||||
|
||||
@@ -36,10 +36,10 @@ async function get(rid) {
|
||||
async function getMany(query, sort, page, limit) {
|
||||
return await coll.find(query).sort(sort).skip((page - 1) * limit).limit(limit).toArray();
|
||||
}
|
||||
async function update(domainId, rid, $set) {
|
||||
await coll.findOneAndUpdate({ domainId, _id: rid }, { $set });
|
||||
let rdoc = await coll.findOne({ domainId, _id: rid });
|
||||
if (!rdoc) throw new RecordNotFoundError(domainId, rid);
|
||||
async function update(rid, $set) {
|
||||
await coll.findOneAndUpdate({ _id: rid }, { $set });
|
||||
let rdoc = await coll.findOne({ _id: rid });
|
||||
if (!rdoc) throw new RecordNotFoundError(rid);
|
||||
return rdoc;
|
||||
}
|
||||
async function count(query) {
|
||||
|
||||
+10
-2
@@ -12,10 +12,17 @@ async function update(_id, update, config) {
|
||||
}
|
||||
/**
|
||||
* Increments the user counter.
|
||||
* @returns {Number} Integer value after increment.
|
||||
* @returns {number} Integer value after increment.
|
||||
*/
|
||||
async function incUserCounter() {
|
||||
return this.update('userCounter', { $inc: { value: 1 } }, { upsert: true });
|
||||
return await this.update('userCounter', { $inc: { value: 1 } }, { upsert: true });
|
||||
}
|
||||
/**
|
||||
* Increments the problem ID counter.
|
||||
* @returns {number} Integer value before increment.
|
||||
*/
|
||||
async function incPidCounter() {
|
||||
return await this.update('userCounter', { $inc: { value: 1 } }, { upsert: true });
|
||||
}
|
||||
async function acquireLock(name) {
|
||||
let value = Math.floor(Math.random() * 0xFFFFFFFF);
|
||||
@@ -35,6 +42,7 @@ async function releaseLockAnyway(name) {
|
||||
module.exports = {
|
||||
get,
|
||||
update,
|
||||
incPidCounter,
|
||||
incUserCounter,
|
||||
acquireLock,
|
||||
releaseLock,
|
||||
|
||||
+14
-23
@@ -1,5 +1,4 @@
|
||||
const
|
||||
domain = require('./domain'),
|
||||
validator = require('../lib/validator'),
|
||||
{ ValidationError, TrainingNotFoundError } = require('../error'),
|
||||
db = require('../service/db.js'),
|
||||
@@ -11,7 +10,7 @@ module.exports = {
|
||||
SETTING_DIFFICULTY_ADMIN: 1,
|
||||
SETTING_DIFFICULTY_AVERAGE: 2,
|
||||
|
||||
async add(domainId, title, content, owner_uid, dag = [], desc = '') {
|
||||
async add(title, content, owner_uid, dag = [], desc = '') {
|
||||
validator.check_title(title);
|
||||
validator.check_intro(content);
|
||||
validator.check_description(desc);
|
||||
@@ -20,12 +19,12 @@ module.exports = {
|
||||
if (nid >= node._id)
|
||||
throw new ValidationError('dag');
|
||||
return await coll.insertOne({
|
||||
domainId, content, owner_uid,
|
||||
content, owner_uid,
|
||||
dag, title, desc, enroll: 0
|
||||
});
|
||||
},
|
||||
count: (domainId, query) => coll.find(Object.assign({ domainId }, query)).count(),
|
||||
async edit(domainId, tid, $set) {
|
||||
count: (query) => coll.find(query).count(),
|
||||
async edit(tid, $set) {
|
||||
if ($set.title) validator.check_title($set.title);
|
||||
if ($set.content) validator.check_intro($set.content);
|
||||
if ($set.desc) validator.check_description($set.desc);
|
||||
@@ -33,28 +32,20 @@ module.exports = {
|
||||
for (let node of $set.dag)
|
||||
for (let nid of node.require_nids)
|
||||
if (nid >= node._id) throw new ValidationError('dag');
|
||||
await coll.findOneAndUpdate({ domainId, tid }, { $set });
|
||||
let tdoc = await coll.findOne({ domainId, tid });
|
||||
if (!tdoc) throw new TrainingNotFoundError(domainId, tid);
|
||||
await coll.findOneAndUpdate({ tid }, { $set });
|
||||
let tdoc = await coll.findOne({ tid });
|
||||
if (!tdoc) throw new TrainingNotFoundError(tid);
|
||||
return tdoc;
|
||||
},
|
||||
async get(domainId, tid) {
|
||||
let tdoc = await coll.findOne({ domainId, tid });
|
||||
if (!tdoc) throw new TrainingNotFoundError(domainId, tid);
|
||||
async get(tid) {
|
||||
let tdoc = await coll.findOne({ tid });
|
||||
if (!tdoc) throw new TrainingNotFoundError(tid);
|
||||
return tdoc;
|
||||
},
|
||||
get_multi: (domainId, query) => coll.find(Object.assign({ domainId }, query)),
|
||||
get_multi_status: (query) => coll.find(query),
|
||||
async get_random_id(query) {
|
||||
let pdocs = coll.find(query);
|
||||
let pcount = await pdocs.count();
|
||||
if (pcount) {
|
||||
let pdoc = await pdocs.skip(Math.floor(Math.random() * pcount)).limit(1).toArray()[0];
|
||||
return pdoc.pid;
|
||||
} else return null;
|
||||
},
|
||||
get_status: (domainId, tid, uid) => coll_status.findOne({ domainId, tid, uid }),
|
||||
set_status: (domainId, tid, uid, $set) => coll_status.findOneAndUpdate({ domainId, tid, uid }, { $set })
|
||||
get_multi: (query) => coll.find( query),
|
||||
get_multi_status: (query) => coll_status.find(query),
|
||||
get_status: (tid, uid) => coll_status.findOne({ tid, uid }),
|
||||
set_status: (tid, uid, $set) => coll_status.findOneAndUpdate({ tid, uid }, { $set })
|
||||
|
||||
};
|
||||
|
||||
|
||||
+17
-45
@@ -1,28 +1,19 @@
|
||||
const
|
||||
{ UserNotFoundError, UserAlreadyExistError, DomainNotFoundError,
|
||||
UserAlreadyDomainMemberError } = require('../error'),
|
||||
{ UserNotFoundError, UserAlreadyExistError } = require('../error'),
|
||||
system = require('./system'),
|
||||
domain = require('./domain'),
|
||||
{ pwhash, validator } = require('../utils'),
|
||||
db = require('../service/db.js'),
|
||||
coll = db.collection('user'),
|
||||
coll_domain = db.collection('domain_user');
|
||||
coll_role = db.collection('role');
|
||||
|
||||
class USER {
|
||||
constructor(user, domainUser = {}) {
|
||||
if (!user) throw new UserNotFoundError();
|
||||
constructor(user) {
|
||||
this._id = user._id;
|
||||
this.email = user.email;
|
||||
this.uname = user.uname;
|
||||
this.priv = user.priv;
|
||||
this.salt = user.salt;
|
||||
this.hash = user.hash;
|
||||
this.perm = domainUser.perm || '0';
|
||||
this.displayName = domainUser.displayName || null;
|
||||
this.domainId = domainUser.domainId || 'system';
|
||||
}
|
||||
hasPriv(priv) {
|
||||
return this.priv & priv;
|
||||
this.perm = user.perm;
|
||||
}
|
||||
hasPerm(perm) {
|
||||
console.log('PERM', perm, this.perm);
|
||||
@@ -31,43 +22,28 @@ class USER {
|
||||
checkPassword(password) {
|
||||
return pwhash.check(password, this.salt, this.hash);
|
||||
}
|
||||
/**
|
||||
* @param {string} role
|
||||
* @param {date} joinAt
|
||||
*/
|
||||
async joinDomain(role, joinAt) {
|
||||
validator.checkRole(role);
|
||||
try {
|
||||
await coll_domain.updateOne(
|
||||
{ domainId: this.domainId, uid: this._id, role: { $exists: false } },
|
||||
{ $set: { role, joinAt: joinAt || new Date() } },
|
||||
{ upsert: true }
|
||||
);
|
||||
} catch (e) {
|
||||
throw new UserAlreadyDomainMemberError(this.domainId, this._id);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
async function getById(_id, domainId) {
|
||||
let dudoc, udoc = await coll.findOne({ _id });
|
||||
if (domainId) {
|
||||
let ddoc = await domain.get(domainId);
|
||||
if (!ddoc) throw new DomainNotFoundError(domainId);
|
||||
dudoc = (await coll_domain.findOne({ uid: _id, domainId })) || {};
|
||||
console.log(dudoc.role, ddoc.roles, { uid: _id, domainId });
|
||||
dudoc.perm = ddoc.roles[dudoc.role || 'default'];
|
||||
}
|
||||
return new USER(udoc, dudoc);
|
||||
async function getById(_id) {
|
||||
let udoc = await coll.findOne({ _id });
|
||||
if (!udoc) throw new UserNotFoundError(_id);
|
||||
let role = await coll_role.findOne({ _id: udoc.role || 'default' });
|
||||
udoc.perm = role.perm;
|
||||
return new USER(udoc);
|
||||
}
|
||||
async function getByUname(uname) {
|
||||
let unameLower = uname.trim().toLowerCase();
|
||||
let udoc = await coll.findOne({ unameLower });
|
||||
if (!udoc) throw new UserNotFoundError(uname);
|
||||
let role = await coll_role.findOne({ _id: udoc.role || 'default' });
|
||||
udoc.perm = role.perm;
|
||||
return new USER(udoc);
|
||||
}
|
||||
async function getByEmail(email) {
|
||||
let emailLower = email.trim().toLowerCase();
|
||||
let udoc = await coll.findOne({ emailLower });
|
||||
if (!udoc) throw new UserNotFoundError(email);
|
||||
let role = await coll_role.findOne({ _id: udoc.role || 'default' });
|
||||
udoc.perm = role.perm;
|
||||
return new USER(udoc);
|
||||
}
|
||||
async function setPassword(uid, password) {
|
||||
@@ -84,10 +60,6 @@ async function setEmail(uid, email) {
|
||||
function setById(uid, args) {
|
||||
coll.findOneAndUpdate({ _id: uid }, { $set: args });
|
||||
}
|
||||
|
||||
function setPriv(uid, priv) {
|
||||
setById(uid, { priv });
|
||||
}
|
||||
async function changePassword(uid, currentPassword, newPassword) {
|
||||
validator.checkPassword(newPassword);
|
||||
let udoc = await getById(uid);
|
||||
@@ -133,5 +105,5 @@ module.exports = {
|
||||
changePassword, create, getByEmail,
|
||||
getById, getByUname, getMany,
|
||||
setById, setEmail,
|
||||
setPassword, setPriv
|
||||
setPassword
|
||||
};
|
||||
Reference in new issue
Block a user