واحد جنایی کوئرا که فعالیت خودش را از سال ۱۳۹۹ آغاز کرده بود، فیلمی از کارآگاه فرهاد -یکی از اولین کارآگاههای کوئرا- دریافت کرده است. در این فیلم فرهاد توسط یک باند مافیایی محاصره شده است و از کوئرا درخواست کمک کرده است. فرهاد به سرنخهای مهمی از عملیاتهای این باند مافیایی دست پیدا کرده است و آنها را داخل یکی از سرورهای امن کوئرا و با چند پیچیدگی امنیتی آپلود کرده است. باند مافیایی که از این ماجرا بسیار عصبانی شده بود، فرهاد را به قتل رساند! حال واحد جنایی کوئرا به کارآگاه کیان و کارآگاه آدرینا ماموریت داده است تا دادههایی که فرهاد بر روی سرور قرار داده است را رمزگشایی کنند.
از آنجایی که فرهاد چندین لایه امنیتی را بر روی سرور تنظیم کرده است، آنها به کمک شما برای پیدا کردن سرنخها نیاز دارند.
## ساختار پروژه
کیان و آدرینا کلاسی به نام `Detective` را طراحی کردند که دارای توابع زیر هست:
<details class="green">
<summary>**تابع** `login`</summary>
این تابع با دریافت `username` و `password` و `URL` صفحه ورود، وظیفه احراز هویت کاربران را به عهده دارد. در صورتی که عملیات احراز هویت موفقیت آمیز باشد، یک فایل `JSON` به فرمت زیر برگردانده میشود:
```json
{
"token": <mark title="توکن احراز هویت کاربر" class="yellow"><Authorization Token></mark>,
"first_name": "Kian",
"last_name": "Majlessi",
"email": "contact@quera.org",
"upload_url": <mark title="URL صفحه آپلود سرنخها" class="yellow"><UPLOAD_URL></mark>
}
```
از آنجایی که `token` و `upload_url` محرمانه هستند؛ لازم هست که شما یک دیکشنری تنها با دو کلید `full_name` و `email` برگردانید.
+ `full_name` یک کاربر نام و نام خانوادگی او است که با یک اسپیس از هم جدا شدهاند.
و در صورتی که عملیات احراز هویت موفقیت آمیز نبود، باید یک `Exception` با پیغام زیر پرتاب کنید:
```
[<mark title="در اینجا کد وضعیتی که از سرور دریافت میکنید را بنویسید" class="red"><STATUS_CODE></mark>]: Unable to log in with provided credentials.
```
### نکات مهم
+ درخواستهای شما به صفحه ورود باید از طریق متد `POST` انجام شوند.
+ سرور فرهاد از **احراز هویت با توکن** استفاده میکند. به این صورت که هر کابر برای لاگین کردن پس از ارسال نام کاربری و رمز عبور خود و در صورت درست بودن اطلاعات، یک نشانهی منحصر به فرد _(Unique Token)_ را به عنوان پاسخ دریافت میکند. از این پس هر ریکوئستی که آن کاربر به ایپیآیهای آن سرور میزند، برای آن که لاگین بودن خود را ثابت کند، باید این نشانهی منحصر به فرد را برای سرور ارسال کند تا سرور بتواند هویت آن شخص را بر اساس این نشانه، تشخیص دهد و به او اجازههای دسترسی لازم را بدهد.
+ برای ارسال توکن به سرور باید مقدار زیر را در Header درخواستهای خود به سرور قرار دهید.
```
Authorization: Token <mark title="توکن دریافتی از سرور" class="red"><Token></mark>
```
+ برای امنیت بیشتر، پس از لاگین کاربر، یک کوکی مخفی در سیستم او ذخیره میشود. برای انجام درخواستهای بعدی لازم است که این کوکی را در سیستم خود در اختیار داشته باشید!
</details>
<details class="teal">
<summary>**تابع** `upload_clues`</summary>
سعید و مهدی که موازی با فرهاد در حال کار بر روی این پرونده بودند، مدارکی را جمعآوری و در پوشهای به نام `secrets` در کنار فایل کلاینت شما قرار دادند. شما باید تمامی این مدارک را پیدا کرده و از طریق متد `PUT` و فیلد `uploaded_files` داخل آدرسی که در مرحله قبل دریافت کردهاید در سرور آپلود کنید.
در نهایت، سرور یک فایل `JSON` که شامل کلیدهای `detail` و `download_url` هست را به شما برمیگرداند. از مقدار `download_url` برای قسمت بعدی سوال استفاده کنید و مقدار `detail` را برای ما برگردانید!
```python
put(url=upload_url, files=[('uploaded_files', open(file_address,"rb")),('uploaded_files', , open(file_address,"rb")), ......])
```
</details>
<details class="purple">
<summary>**تابع** `html_scraper`</summary>
تبریک! شما به اسناد فرهاد دسترسی پیدا کردید. اما عجله نکنید! این تازه اول راه است. فرهاد که هیچوقت نمیخواست باند مافیا به اسناد دست پیدا کند، آنها را در مکانهای مختلفی قرار داد و لینکهایش را در صفحه `HTML` ای مخفی کرد. شما در این تابع با استفاده از متد `GET` و آدرس صفحهای که در مرحله قبل دریافت کردهاید، میتوانید این صفحه `HTML` را دانلود کنید. حال، تمامی لینکهای آن و عنوانهایش را پیدا کنید و در دیکشنریای به تیم جنایی کوئرا برگردانید. کلید دیکشنری شما باید عنوان لینک و مقدار آن آدرس لینک باشد.
+ **توجه کنید** که تنها لینکهایی را باید داخل دیکشنری قرار دهید که دارای عنوان باشند.
</details>
<details class="grey">
<summary>محتویات فایل `solution.py`</summary>
```python solution.py
class Detective:
def login(self, username: str, password: str, login_url: str):
pass
#TODO: Complete login Function
def upload_clues(self):
pass
#TODO: Complete upload_clues Function
def html_scraper(self):
pass
#TODO: Complete html_scraper Function
```
همچنین شما میتوانید پروژه اولیه را از [این لینک](/contest/assignments/51094/download_problem_initial_project/174128/) دانلود کنید.
</details>
## پاسخ ارسالی
در پاسخ ارسالی خود میتوانید از هر کتابخانهای که لازم میدانید استفاده کنید. اما در فایل ارسالی خود، علاوه بر فایل `solution.py` که حاوی راهحل شما است، باید فایلی با نام `python_requirements.txt` نیز موجود باشد که در آن نام کتابخانههای مورد نیاز و شمارهٔ نسخهٔ آنها به فرمت زیر در آن موجود باشد:
```txt python_requirements.txt
firstlib==1.2.3
secondlib==4.5.6
...
```
## ساختار فایل ارسالی
ساختار فایل `.zip` ارسالی شما باید به صورت زیر باشد:
```
<your_zip_file_name.zip>
├── solution.py
└── python_requirements.txt
```