remove domain system

This commit is contained in:
masnn committed 2020-04-03 20:56:08 +08:00
1 parent 7fa4a58abe
commit fc26af30ef
31 files changed
+709 -1242

No files matched your search

+152 -22
View File
@@ -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
View File
@@ -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:
-315
View File
@@ -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
View File
@@ -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) {
+4 -4
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
};