async def get(self, *, rid: objectid.ObjectId): rdoc = await record.get(rid) if not rdoc: raise error.RecordNotFoundError(rid) # TODO(iceboy): Check domain permission, permission for visibility in place. if rdoc['domain_id'] != self.domain_id: self.redirect( self.reverse_url('record_detail', rid=rid, domain_id=rdoc['domain_id'])) return if rdoc['tid']: show_status, tdoc = await self.rdoc_contest_visible(rdoc) else: show_status, tdoc = True, None # TODO(twd2): futher check permission for visibility. if (not self.own(rdoc, field='uid') and not self.has_perm(builtin.PERM_READ_RECORD_CODE) and not self.has_priv(builtin.PRIV_READ_RECORD_CODE)): del rdoc['code'] if not show_status and 'code' not in rdoc: if tdoc['doc_type'] == document.TYPE_CONTEST: raise error.PermissionError( builtin.PERM_VIEW_CONTEST_HIDDEN_SCOREBOARD) else: # TYPE_HOMEWORK raise error.PermissionError( builtin.PERM_VIEW_HOMEWORK_HIDDEN_SCOREBOARD) udoc, dudoc = await asyncio.gather( user.get_by_uid(rdoc['uid']), domain.get_user(self.domain_id, rdoc['uid'])) try: pdoc = await problem.get(rdoc['domain_id'], rdoc['pid']) except error.ProblemNotFoundError: pdoc = {} if show_status and 'judge_uid' in rdoc: judge_udoc = await user.get_by_uid(rdoc['judge_uid']) else: judge_udoc = None # check permission for visibility: hidden problem if pdoc.get( 'hidden', False) and not self.has_perm(builtin.PERM_VIEW_PROBLEM_HIDDEN): pdoc = None url_prefix = '/d/{}'.format(urllib.parse.quote(self.domain_id)) self.render('record_detail.html', rdoc=rdoc, udoc=udoc, dudoc=dudoc, pdoc=pdoc, tdoc=tdoc, judge_udoc=judge_udoc, show_status=show_status, socket_url=url_prefix + '/records/{}/conn'.format(rid)) # FIXME(twd2): magic
async def post(self, *, src_domain_id: str, src_pids: str, numeric_pid: bool = False, hidden: bool = False): src_ddoc, src_dudoc = await asyncio.gather( domain.get(src_domain_id), domain.get_user(src_domain_id, self.user['_id'])) if not src_dudoc: src_dudoc = {} if not self.dudoc_has_perm(ddoc=src_ddoc, dudoc=src_dudoc, udoc=self.user, perm=builtin.PERM_VIEW_PROBLEM): # TODO: This is the source domain's PermissionError. raise error.PermissionError(builtin.PERM_VIEW_PROBLEM) src_pids = misc.dedupe( map(document.convert_doc_id, src_pids.replace('\r\n', '\n').split('\n'))) if len(src_pids) > self.MAX_PROBLEMS_PER_REQUEST: raise error.BatchCopyLimitExceededError( self.MAX_PROBLEMS_PER_REQUEST, len(src_pids)) pdocs = await problem.get_multi(domain_id=src_domain_id, doc_id={'$in': src_pids}) \ .sort('doc_id', 1) \ .to_list() exist_pids = [pdoc['doc_id'] for pdoc in pdocs] if len(src_pids) != len(exist_pids): for pid in src_pids: if pid not in exist_pids: raise error.ProblemNotFoundError(src_domain_id, pid) for pdoc in pdocs: if pdoc.get('hidden', False): if not self.dudoc_has_perm( ddoc=src_ddoc, dudoc=src_dudoc, udoc=self.user, perm=builtin.PERM_VIEW_PROBLEM_HIDDEN): # TODO: This is the source domain's PermissionError. raise error.PermissionError( builtin.PERM_VIEW_PROBLEM_HIDDEN) for pdoc in pdocs: pid = None if numeric_pid: pid = await domain.inc_pid_counter(self.domain_id) await problem.copy(pdoc, self.domain_id, self.user['_id'], pid, hidden) self.redirect(self.reverse_url('problem_main'))
async def post_copy_to_domain(self, *, pid: document.convert_doc_id, dest_domain_id: str, numeric_pid: bool = False, hidden: bool = False): uid = self.user['_id'] pdoc = await problem.get(self.domain_id, pid, uid) if pdoc.get('hidden', False): self.check_perm(builtin.PERM_VIEW_PROBLEM_HIDDEN) ddoc, dudoc = await asyncio.gather( domain.get(dest_domain_id), domain.get_user(dest_domain_id, uid)) if not dudoc: dudoc = {} if not self.dudoc_has_perm(dudoc=dudoc, perm=builtin.PERM_CREATE_PROBLEM, ddoc=ddoc, udoc=self.user): # TODO: This is the destination domain's PermissionError. raise error.PermissionError(builtin.PERM_CREATE_PROBLEM) pid = None if numeric_pid: pid = await domain.inc_pid_counter(dest_domain_id) pid = await problem.copy(pdoc, dest_domain_id, uid, pid, hidden) new_url = self.reverse_url('problem_settings', pid=pid, domain_id=dest_domain_id) self.json_or_redirect(new_url, new_problem_url=new_url)
async def get(self, *, pid: document.convert_doc_id, page: int=1): uid = self.user['_id'] if self.has_priv(builtin.PRIV_USER_PROFILE) else None pdoc = await problem.get(self.domain_id, pid, uid) if not self.has_perm(builtin.PERM_VIEW_PROBLEM_SOLUTION) and \ (pdoc['psdoc'] is None or 'status' not in pdoc['psdoc'] or \ pdoc['psdoc']['status'] != constant.record.STATUS_ACCEPTED): raise error.PermissionError(builtin.PERM_VIEW_PROBLEM_SOLUTION) if pdoc.get('hidden', False): self.check_perm(builtin.PERM_VIEW_PROBLEM_HIDDEN) psdocs, pcount, pscount = await pagination.paginate( problem.get_multi_solution(self.domain_id, pdoc['doc_id']).sort([("vote",-1)]), page, self.SOLUTIONS_PER_PAGE) uids = {pdoc['owner_uid']} uids.update(psdoc['owner_uid'] for psdoc in psdocs) for psdoc in psdocs: if 'reply' in psdoc: uids.update(psrdoc['owner_uid'] for psrdoc in psdoc['reply']) udict, dudict, pssdict = await asyncio.gather( user.get_dict(uids), domain.get_dict_user_by_uid(self.domain_id, uids), problem.get_dict_solution_status( self.domain_id, (psdoc['doc_id'] for psdoc in psdocs), self.user['_id'])) dudict[self.user['_id']] = self.domain_user path_components = self.build_path( (self.translate('problem_main'), self.reverse_url('problem_main')), (pdoc['title'], self.reverse_url('problem_detail', pid=pdoc['doc_id'])), (self.translate('problem_solution'), None)) self.render('problem_solution.html', path_components=path_components, pdoc=pdoc, psdocs=psdocs, page=page, pcount=pcount, pscount=pscount, udict=udict, dudict=dudict, pssdict=pssdict)
async def get(self, *, rid: objectid.ObjectId): rdoc = await record.get(rid) if not rdoc: raise error.RecordNotFoundError(rid) # TODO(iceboy): Check domain permission, permission for visibility in place. if rdoc['domain_id'] != self.domain_id: self.redirect( self.reverse_url('record_detail', rid=rid, domain_id=rdoc['domain_id'])) return # check permission for visibility: contest show_status = True if rdoc['tid']: now = datetime.datetime.utcnow() try: tdoc = await contest.get(rdoc['domain_id'], rdoc['tid']) show_status = contest.RULES[tdoc['rule']].show_func(tdoc, now) \ or self.has_perm(builtin.PERM_VIEW_CONTEST_HIDDEN_STATUS) except error.DocumentNotFoundError: tdoc = None else: tdoc = None # TODO(twd2): futher check permission for visibility. if (not self.own(rdoc, field='uid') and not self.has_perm(builtin.PERM_READ_RECORD_CODE) and not self.has_priv(builtin.PRIV_READ_RECORD_CODE)): del rdoc['code'] if not show_status and 'code' not in rdoc: raise error.PermissionError( builtin.PERM_VIEW_CONTEST_HIDDEN_STATUS) udoc, dudoc = await asyncio.gather( user.get_by_uid(rdoc['uid']), domain.get_user(self.domain_id, rdoc['uid'])) try: pdoc = await problem.get(rdoc['domain_id'], rdoc['pid']) except error.ProblemNotFoundError: pdoc = {} if show_status and 'judge_uid' in rdoc: judge_udoc = await user.get_by_uid(rdoc['judge_uid']) else: judge_udoc = None # check permission for visibility: hidden problem if pdoc.get( 'hidden', False) and not self.has_perm(builtin.PERM_VIEW_PROBLEM_HIDDEN): pdoc = None self.render('record_detail.html', rdoc=rdoc, udoc=udoc, dudoc=dudoc, pdoc=pdoc, tdoc=tdoc, judge_udoc=judge_udoc, show_status=show_status)
def check_perm(self, perm): if not self.has_perm(perm): raise error.PermissionError(perm)