واحد جنایی کوئرا که فعالیت خودش را از سال ۱۳۹۹ آغاز کرده بود، فیلمی از کارآگاه فرهاد -یکی از اولین کارآگاههای کوئرا- دریافت کرده است. در این فیلم فرهاد توسط یک باند مافیایی محاصره شده است و از کوئرا درخواست کمک کرده است. فرهاد به سرنخهای مهمی از عملیاتهای این باند مافیایی دست پیدا کرده است و آنها را داخل یکی از سرورهای امن کوئرا و با چند پیچیدگی امنیتی آپلود کرده است. باند مافیایی که از این ماجرا بسیار عصبانی شده بود، فرهاد را به قتل رساند! حال واحد جنایی کوئرا به کارآگاه کیان و کارآگاه آدرینا ماموریت داده است تا دادههایی که فرهاد بر روی سرور قرار داده است را رمزگشایی کنند. از آنجایی که فرهاد چندین لایه امنیتی را بر روی سرور تنظیم کرده است، آنها به کمک شما برای پیدا کردن سرنخها نیاز دارند.
ساختار پروژه
کیان و آدرینا کلاسی به نام Detective
را طراحی کردند که دارای توابع زیر هست:
تابع login
این تابع با دریافت login
username
و password
و URL
صفحه ورود، وظیفه احراز هویت کاربران را به عهده دارد. در صورتی که عملیات احراز هویت موفقیت آمیز باشد، یک فایل JSON
به فرمت زیر برگردانده میشود:
{
"token": <Authorization Token>,
"first_name": "Kian",
"last_name": "Majlessi",
"email": "contact@quera.org",
"upload_url": <UPLOAD_URL>
}
از آنجایی که token
و upload_url
محرمانه هستند؛ لازم هست که شما یک دیکشنری تنها با دو کلید full_name
و email
برگردانید.
full_name
یک کاربر نام و نام خانوادگی او است که با یک اسپیس از هم جدا شدهاند.
و در صورتی که عملیات احراز هویت موفقیت آمیز نبود، باید یک Exception
با پیغام زیر پرتاب کنید:
[<STATUS_CODE>]: Unable to log in with provided credentials.
نکات مهم
- درخواستهای شما به صفحه ورود باید از طریق متد
POST
انجام شوند. - سرور فرهاد از احراز هویت با توکن استفاده میکند. به این صورت که هر کابر برای لاگین کردن پس از ارسال نام کاربری و رمز عبور خود و در صورت درست بودن اطلاعات، یک نشانهی منحصر به فرد (Unique Token) را به عنوان پاسخ دریافت میکند. از این پس هر ریکوئستی که آن کاربر به ایپیآیهای آن سرور میزند، برای آن که لاگین بودن خود را ثابت کند، باید این نشانهی منحصر به فرد را برای سرور ارسال کند تا سرور بتواند هویت آن شخص را بر اساس این نشانه، تشخیص دهد و به او اجازههای دسترسی لازم را بدهد.
- برای ارسال توکن به سرور باید مقدار زیر را در Header درخواستهای خود به سرور قرار دهید.
Authorization: Token <Token>
- برای امنیت بیشتر، پس از لاگین کاربر، یک کوکی مخفی در سیستم او ذخیره میشود. برای انجام درخواستهای بعدی لازم است که این کوکی را در سیستم خود در اختیار داشته باشید!
تابع upload_clues
سعید و مهدی که موازی با فرهاد در حال کار بر روی این پرونده بودند، مدارکی را جمعآوری و در پوشهای به نام upload_clues
secrets
در کنار فایل کلاینت شما قرار دادند. شما باید تمامی این مدارک را پیدا کرده و از طریق متد PUT
و فیلد uploaded_files
داخل آدرسی که در مرحله قبل دریافت کردهاید در سرور آپلود کنید.
در نهایت، سرور یک فایل JSON
که شامل کلیدهای detail
و download_url
هست را به شما برمیگرداند. از مقدار download_url
برای قسمت بعدی سوال استفاده کنید و مقدار detail
را برای ما برگردانید!
put(url=upload_url, files=[('uploaded_files', open(file_address,"rb")),('uploaded_files', , open(file_address,"rb")), ......])
تابع html_scraper
تبریک! شما به اسناد فرهاد دسترسی پیدا کردید. اما عجله نکنید! این تازه اول راه است. فرهاد که هیچوقت نمیخواست باند مافیا به اسناد دست پیدا کند، آنها را در مکانهای مختلفی قرار داد و لینکهایش را در صفحه html_scraper
HTML
ای مخفی کرد. شما در این تابع با استفاده از متد GET
و آدرس صفحهای که در مرحله قبل دریافت کردهاید، میتوانید این صفحه HTML
را دانلود کنید. حال، تمامی لینکهای آن و عنوانهایش را پیدا کنید و در دیکشنریای به تیم جنایی کوئرا برگردانید. کلید دیکشنری شما باید عنوان لینک و مقدار آن آدرس لینک باشد.
- توجه کنید که تنها لینکهایی را باید داخل دیکشنری قرار دهید که دارای عنوان باشند.
محتویات فایل solution.py
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
همچنین شما میتوانید پروژه اولیه را از این لینک دانلود کنید.
پاسخ ارسالی
در پاسخ ارسالی خود میتوانید از هر کتابخانهای که لازم میدانید استفاده کنید. اما در فایل ارسالی خود، علاوه بر فایل solution.py
که حاوی راهحل شما است، باید فایلی با نام python_requirements.txt
نیز موجود باشد که در آن نام کتابخانههای مورد نیاز و شمارهٔ نسخهٔ آنها به فرمت زیر در آن موجود باشد:
firstlib==1.2.3
secondlib==4.5.6
...
ساختار فایل ارسالی
ساختار فایل .zip
ارسالی شما باید به صورت زیر باشد:
<your_zip_file_name.zip>
├── solution.py
└── python_requirements.txt
ارسال پاسخ برای این سؤال