diff --git a/.verify-helper/docs/static/document.ja.md b/.verify-helper/docs/static/document.ja.md index c2b0892a..b2c5c054 100644 --- a/.verify-helper/docs/static/document.ja.md +++ b/.verify-helper/docs/static/document.ja.md @@ -113,7 +113,7 @@ verification_file_suffix = ".test.sed" | [Library Checker](https://judge.yosupo.jp/) | | | [Aizu Online Judge](https://onlinejudge.u-aizu.ac.jp/home) | | | [HackerRank](https://www.hackerrank.com/) | | -| [AtCoder](https://atcoder.jp) | 環境変数 `DROPBOX_TOKEN` の設定が必要です。token の値は `$ oj d --system https://atcoder.jp/contests/agc001/tasks/agc001_a` として表示されるヒントに従って取得してください。 | +| [AtCoder](https://atcoder.jp) | 環境変数 `DROPBOX_TOKEN` の設定が必要です。token の値は `$ oj d --system https://atcoder.jp/contests/agc001/tasks/agc001_a` として表示されるヒントに従って取得してください。
(2024.03.16追記)
現在ヘルプ通りにはトークンを取得できなくなっています。まずからAppを作成し、Permissions で `files.metadata.read` と `sharing.read` にチェックをつけます。ここで、generate access token で一時的なトークンを作成し、環境変数`DROPBOX_TOKEN`に設定することができますが、これは短期間で失効してしまうので、再設定が面倒な方はを参考に、Refresh Tokenを取得して環境変数`DROPBOX_REFRESH_TOKEN`を、App作成時に出てきたApp KeyとApp Secretをそれぞれ環境変数`DROPBOX_APP_KEY`,`DROPBOX_APP_SECRET`として登録してください。これらを用いて毎回アクセストークンを自動で生成して適用するようになります。 | | [yukicoder](https://yukicoder.me) | 環境変数 `YUKICODER_TOKEN` の設定が必要です。[ヘルプ - yukicoder](https://yukicoder.me/help) の「ログインしてないと使えない機能をAPIとして使いたい」の節や [暗号化されたシークレットの作成と利用 - GitHub ヘルプ](https://help.github.com/ja/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets#creating-encrypted-secrets) 参考にして設定してください。 | これらの他サービスはテストケースを利用できる形で公開してくれていないため利用できません。 diff --git a/.verify-helper/docs/static/document.md b/.verify-helper/docs/static/document.md index ee10850a..a966af7b 100644 --- a/.verify-helper/docs/static/document.md +++ b/.verify-helper/docs/static/document.md @@ -112,7 +112,7 @@ verification_file_suffix = ".test.sed" | [Library Checker](https://judge.yosupo.jp/) | | | [Aizu Online Judge](https://onlinejudge.u-aizu.ac.jp/home) | | | [HackerRank](https://www.hackerrank.com/) | | -| [AtCoder](https://atcoder.jp) | You must set the `DROPBOX_TOKEN` environment variable. You can obtain the token by following the HINT message shown by `$ oj d --system https://atcoder.jp/contests/agc001/tasks/agc001_a`. | +| [AtCoder](https://atcoder.jp) | You must set the `DROPBOX_TOKEN` environment variable. You can obtain the token by following the HINT message shown by `$ oj d --system https://atcoder.jp/contests/agc001/tasks/agc001_a`.
(Added on 2024.03.16)
Currently, obtaining tokens according to the help is not possible. First, create an App from , and check files.metadata.read and sharing.read under Permissions. Here, you can generate a temporary token by clicking on "generate access token" and set it to the environment variable `DROPBOX_TOKEN`. However, since this token expires after a short period, for those who find reconfiguration troublesome, please refer to to obtain a Refresh Token and set it to the environment variable `DROPBOX_REFRESH_TOKEN`, and register the App Key and App Secret obtained during App creation as environment variables `DROPBOX_APP_KEY` and `DROPBOX_APP_SECRET`, respectively. By using these, an access token will be automatically generated and applied each time.| | [yukicoder](https://yukicoder.me) | You must set the `YUKICODER_TOKEN` environment variable. See 「ログインしてないと使えない機能をAPIとして使いたい」 in [ヘルプ - yukicoder](https://yukicoder.me/help) and [Creating and using encrypted secrets - GitHub Help](https://help.github.com/en/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets). | Other judging platforms do not currently publish the test cases in usable forms, and so are not currently supported. diff --git a/onlinejudge_verify/verify.py b/onlinejudge_verify/verify.py index 83a0b096..a7353757 100644 --- a/onlinejudge_verify/verify.py +++ b/onlinejudge_verify/verify.py @@ -1,14 +1,18 @@ # Python Version: 3.x import hashlib +import json import math import os import pathlib +import re import subprocess import time import traceback from logging import getLogger from typing import * +import requests + import onlinejudge import onlinejudge_verify.languages.list import onlinejudge_verify.marker @@ -34,7 +38,10 @@ def succeeded(self) -> bool: def exec_command(command: List[str]): # NOTE: secrets like YUKICODER_TOKEN are masked - logger.info('$ %s', ' '.join(command)) + # dropbox-tokenを新規に取得する場合は、そのトークンが表示されるのでそれもマスクする + dropbox_token_pattern = re.compile(r'(--dropbox-token)\s+([^\s]+)') + message = dropbox_token_pattern.sub(r'\1 ***', ' '.join(command)) + logger.info('$ %s', message) cwd = pathlib.Path.cwd() try: @@ -47,6 +54,19 @@ def exec_command(command: List[str]): os.chdir(str(cwd)) +def get_fresh_dropbox_token() -> str: + data = { + 'grant_type': 'refresh_token', + 'refresh_token': os.environ['DROPBOX_REFRESH_TOKEN'], + } + response = requests.post('https://api.dropbox.com/oauth2/token', data=data, auth=(os.environ['DROPBOX_APP_KEY'], os.environ['DROPBOX_APP_SECRET']), timeout=30) + try: + data = response.json() + return data.get('access_token', '') + except json.JSONDecodeError: + return '' + + def verify_file(path: pathlib.Path, *, compilers: List[str], tle: float, jobs: int) -> Optional[bool]: logger.info('verify: %s', path) @@ -81,6 +101,9 @@ def verify_file(path: pathlib.Path, *, compilers: List[str], tle: float, jobs: i if os.environ.get('DROPBOX_TOKEN'): command += ['--dropbox-token', os.environ['DROPBOX_TOKEN']] + # 短期間で失効するDROPBOX_TOKENを新規に取得するオプションを用意する + elif os.environ.get('DROPBOX_REFRESH_TOKEN') and os.environ.get('DROPBOX_APP_KEY') and os.environ.get('DROPBOX_APP_SECRET'): + command += ['--dropbox-token', get_fresh_dropbox_token()] if os.environ.get('YUKICODER_TOKEN'): command += ['--yukicoder-token', os.environ['YUKICODER_TOKEN']] try: