diff --git a/remote_judger/src/providers/uoj.ts b/remote_judger/src/providers/uoj.ts index ee54086..a8ffda7 100644 --- a/remote_judger/src/providers/uoj.ts +++ b/remote_judger/src/providers/uoj.ts @@ -100,45 +100,60 @@ export default class UOJProvider implements IBasicProvider { } static constructFromAccountData(data) { - throw new Error('Method not implemented.'); + return new this({ + type: 'uoj', + cookie: Object.entries(data).map(([key, value]) => `${key}=${value}`), + }); } cookie: string[] = []; csrf: string; get(url: string) { - logger.debug('get', url); + logger.debug('get', url, this.cookie); + if (!url.includes('//')) url = `${this.account.endpoint || 'https://uoj.ac'}${url}`; + const req = superagent .get(url) .set('Cookie', this.cookie) .set('User-Agent', USER_AGENT); + if (this.account.proxy) return req.proxy(this.account.proxy); + return req; } post(url: string) { logger.debug('post', url, this.cookie); + if (!url.includes('//')) url = `${this.account.endpoint || 'https://uoj.ac'}${url}`; + const req = superagent .post(url) .set('Cookie', this.cookie) .set('User-Agent', USER_AGENT) .type('form'); + if (this.account.proxy) return req.proxy(this.account.proxy); + return req; } async getCsrfToken(url: string) { const { text: html, header } = await this.get(url); + if (header['set-cookie']) { this.cookie = header['set-cookie']; } + let value = /_token *: *"(.+?)"/g.exec(html); if (value) return value[1]; + value = /_token" value="(.+?)"/g.exec(html); + return value?.[1]; } @@ -150,7 +165,11 @@ export default class UOJProvider implements IBasicProvider { async ensureLogin() { if (await this.loggedIn) return true; + + if (!this.account.handle) return false; + logger.info('retry login'); + const _token = await this.getCsrfToken('/login'); const { header, text } = await this.post('/login').send({ _token, @@ -159,11 +178,14 @@ export default class UOJProvider implements IBasicProvider { // NOTE: you should pass a pre-hashed key! password: this.account.password, }); + if (header['set-cookie'] && this.cookie.length === 1) { header['set-cookie'].push(...this.cookie); this.cookie = header['set-cookie']; } + if (text === 'ok') return true; + return text; } @@ -175,6 +197,16 @@ export default class UOJProvider implements IBasicProvider { next, end ) { + if (!(await this.ensureLogin())) { + await end({ + error: true, + status: 'Judgment Failed', + message: 'Login failed', + }); + + return null; + } + const programType = LANGS_MAP[lang] || LANGS_MAP['C++']; const comment = programType.comment; diff --git a/web/app/controllers/subdomain/api/remote_judge/custom_account_validator.php b/web/app/controllers/subdomain/api/remote_judge/custom_account_validator.php index 7e1b8d7..71cc969 100644 --- a/web/app/controllers/subdomain/api/remote_judge/custom_account_validator.php +++ b/web/app/controllers/subdomain/api/remote_judge/custom_account_validator.php @@ -97,6 +97,29 @@ if ($type == 'luogu') { return true; } + return false; + }, 3); +} else if ($type == 'uoj') { + $curl->setFollowLocation(); + $curl->setCookie('UOJSESSID', UOJRequest::post('UOJSESSID', 'is_string', '')); + + retry_loop(function () use (&$curl, &$res) { + $curl->get(UOJRemoteProblem::$providers['uoj']['url'] . '/login'); + + if ($curl->error) { + return false; + } + + if (str_starts_with($curl->responseHeaders['Content-Type'], 'text/html')) { + if (str_contains($curl->response, '
console.log(JSON.parse(localStorage.appState).token)
的输出结果。')))
);
+ } else if (oj == 'uoj') {
+ var uoj_account_data = {"UOJSESSID": ""};
+ var input_uoj_uojsessid = $('');
+
+ if ('localStorage' in window) {
+ try {
+ var uoj_account_data_str = localStorage.getItem('uoj_remote_judge_uoj_account_data');
+ if (uoj_account_data_str) {
+ uoj_account_data = JSON.parse(uoj_account_data_str);
+ }
+ } catch (e) {}
+
+ var save_uoj_account_data = function() {
+ localStorage.setItem('uoj_remote_judge_uoj_account_data', JSON.stringify(uoj_account_data));
+ }
+ }
+
+ input_uoj_uojsessid.change(function() {
+ uoj_account_data.UOJSESSID = $(this).val();
+ input_my_account_data.val(JSON.stringify(uoj_account_data));
+ save_uoj_account_data();
+ my_account_validation_status.html('待验证');
+ });
+
+ my_account_validation_btn.click(function() {
+ validate_my_account({
+ type: 'uoj',
+ UOJSESSID: input_uoj_uojsessid.val(),
+ });
+ });
+
+ input_my_account_data.val(JSON.stringify(uoj_account_data));
+ input_uoj_uojsessid.val(uoj_account_data.UOJSESSID);
+
+ if (uoj_account_data.UOJSESSID) {
+ validate_my_account({
+ type: 'uoj',
+ UOJSESSID: uoj_account_data.UOJSESSID,
+ });
+ }
+
+ div_submit_type_my.append(
+ $('')
+ .append($('').append(''))
+ .append($('').append(input_uoj_uojsessid))
+ .append($('').append($('').append('请填入 Cookie 中的 UOJSESSID
。')))
+ ).append(input_my_account_data);
}
$(this).append(