Генерация одноразовых ссылок на файл

Генерация одноразовых ссылок на файл

от Дмитрий Пименов -
Количество ответов: 7

Добрый день. Возможно ли в мудл реализовать генерацию одноразовых ссылок на файл? Существует ли плагин для этого? Возможно ли это реализовать, не залезая в код в мудл? Работать должен по принципу наподобие токена. Т.е. в ссылку на файл будет добавляться специальный параметр например ?sid=dsf788hjhbjnjknehnjnjn . примеры реализации  такого в сети есть. ну вот как именно это приклеить мудл нет. Делается это для защиты от скачивания.

В ответ на Дмитрий Пименов

Re: Генерация одноразовых ссылок на файл

от Дмитрий Пименов -
Это будет видео файл. стандартные возможности вставки в видео такой защиты не предусматривают. Какой тип плагина это будет исходя из http://docs.moodle.org/dev/Plugins ?
В ответ на Дмитрий Пименов

Re: Генерация одноразовых ссылок на файл

от Vadim Dvorovenko -
Изображение пользователя Developers Изображение пользователя Майнтейнер перевода

Вам, скорее всего, потребуется activity. Я бы посоветовал взять за основу существующий плагин /mod/resource, скопировать, переименовать везде в папках, убедиться, что он установится под новым именем, и после этого допиливать.

Как таковой токен даже не потребуется. За просмотр файла отвечает страница /mod/resource/view.php. Этот файл делает переадресацию на /pluginfile.php, который, в свою очередь, и отдаёт файл. Он отправляет файл через функцию resource_pluginfile в /mod/resource/lib.php. За непосредственную отправку отвечает функция send_stored_file.

Исправив resource_pluginfile() и, при необходимости, view.php, вы сможете контролировать, сколько именно раз пользователь уже скачивал этот файл, и, в зависимости от этого, отдавать файл. Там же и реализуете свою прочую логику (например, на случай обрывов всё-таки разрешать повторные попытки скачивания в течение часа после первой скачки). Обратите внимание, если переименуете плагин в myresource, то и функцию тоже нужно будет переименовать в myresource_pluginfile()

Где и как хранить историю скачивания - по вашему усмотрению. Можно сделать для этого отдельную таблицу, можно просто проверять по логам, были ли скачивания у этого пользователя в этом модуле, но поиск по логам может быть долгим, плюс логи могут через какое-то время очищаться, и тогда пользователь сможет снова скачать файл

В ответ на Vadim Dvorovenko

Re: Генерация одноразовых ссылок на файл

от Дмитрий Пименов -

Спасибо за ответ. Прислушаюсь к вашему способу. Думаю он проще. 

Хотел делать уже так -  написать собственный класс для плеера и оформить его в виде плагина типа media/plugins . Класс будет подобен существующим плеерам только с изменённым методами формирования ссылки. Далее. Подставим этот новый плеер для расширения mp4 по умолчанию в настройках мулла. 

Хотел сделать по такому принципу как в этом примере https://webformyself.com/sozdanie-odnorazovyx-url-adresov/

Ссылки на ресурсы я так понял что хранятся в базе в таблице 'url'. Например domen.ru/pluginfile.php/122/mod_assign/intro/video.mp4. Пусть так и хранятся. 

Если пользователь продвинутый, то он может посмотреть в исходном коде в теге source увидеть ссылку

<video controls="true">

<source src="http://domen.ru/pluginfile.php/122/mod_assign/intro/video.mp4">

</video>

Cсылку, исходя  из примера на сайте webformyself.com по генерации одноразовых ссылок  получается надо  сделать такого вида domen.ru/pluginfile.php?hash=ea878a09c00a2866c489f1ac06a6a5a6  Т.е что бы в ней не было название файла /122/mod_assign/intro/video.mp4, потому что если пользователь перейдет domen.ru/pluginfile.php/122/mod_assign/intro/video.mp4,  то он все равно этот файл получит. 

Если ссылка на видео формируется внутри мудл, то мы её показываем и дописываем хеш... domen.ru/pluginfile.php?hash=ea878a09c00a2866c489f1ac06a6a5a6  и одновременно дописываем в txt файл хеш  - ea878a09c00a2866c489f1ac06a6a5a6. если по этой ссылке прошлись, то мы удаляем хеш из txt файла. Таким образом пройдясь по ней еще раз и проверив наличия хеша в txt файле, которого там уже нет, то ссылка будет неправильной.


Вот. Вадим, это реально сделать в мудл? или не стоит так делать?

В ответ на Дмитрий Пименов

Re: Генерация одноразовых ссылок на файл

от Alex Djachenko -
Изображение пользователя Developers Изображение пользователя Майнтейнер перевода Изображение пользователя ООО "Открытые Технологии" Изображение пользователя Тестер Moodle Изображение пользователя Эксперт по Moodle
Обычно, такие задачи мы решаем через плагин "фильтр".
Фильтр написать гораздо проще (а значит - дешевле, даже если пишете сами, освободившееся время может быть потрачено с бОльшей пользой): гораздо меньше обязательных к реализации методов, как при добавлении в курс, так и при бекапе и восстановлении. Кроме того, фильтр позволит использовать ссылки на видео во всех уже существующих модулях, что тоже полезно (например, добавить видеоролик в лекцию или в тест).

Дальше можно выделить две архитектуры верификации:

1. Криптографическая: коды нигде не сохраняются, к каждой ссылке добавляется временная метка (для контроля устаревания) и хеш-код, например sha1($time.$url.$secret), где $secret - секретный пароль.
Плюс - в простоте реализации и самого фильтра и проверки на стороне медиаархива.
Минусы - вся защита держится на серкретности строки $secret и рассинхрон часов на сервере с Moodle и сервере с медиаархивом приведет к неработоспособности ссылок.

2. На основе случайных ключей: ссылки по тексту заменяются на внутренний редирект на стороне Moodle. Когда пользователь перешел на скрипт редиректа, он формирует одноразовый ключ и помещает его в таблицу одноразовых ключей (либо запрашивает одноразовый ключ от медиаархива), затем, присоединяет одноразовый ключ к URL и редиректит пользователя на него. Медиаархив проверяет наличие одноразового ключа в базе данных, срок его жизни, затем открывает пользователю доступ и удаляет ключ из базы данных.
В ответ на Дмитрий Пименов

Re: Генерация одноразовых ссылок на файл

от Vadim Dvorovenko -
Изображение пользователя Developers Изображение пользователя Майнтейнер перевода

Не храните записи в txt файле. Храните из в базе данных.

Для того, чтобы заставить pluginfile.php обрабатывать новый для него параметр hash, вам придется исправить этот файл. А этот файл общий для всех плагинов и относится к ядру системы, таким образом, вы сделаете не плагин, а покалечите систему.

Единственный callback из pluginfile.php к плагинам, это вызов функции имямодуля_pluginfile. Если такая есть, то файл отдаёт она сама. Если таковой нет, то считается, что ограничений на доступ к файлу нет (кроме входа в систему и доступа к курсу), и файл отдаётся без ограничений.

В таблице url хранятся ссылки ресурса типа гиперссылка. Ссылки на ресурсы типа файл хранятся в таблице resource. url - для ресурсов, внешних, по отношению к moodle, то есть когда видео у вас хранится во внешней системе. В этом случае, вам нужно, чтобы механизм одноразового доступа реализовывался как раз внешней системой, а вы бы только правильно пересылали пользователя из moodle, это то, о чём написал Аlex Djachenko.

Если вы хотите хранить видео в moodle, то вам нужно смотреть не на url, а на resource, как я писал выше. В этом случае секретные ссылки и хэши не нужны, так как у moodle и так есть информация о том, сколько раз уже этот пользователь смотрел этот файл. Ни фильтр, ни плеер не смогут ограничить отдачу файла, поскольку у них нет методов, отвечающих за отдачу файлов. Если будете хранить файл видео в moodle - без activity никак не обойтись.

В ответ на Vadim Dvorovenko

Re: Генерация одноразовых ссылок на файл

от Дмитрий Пименов -

Спасибо Вадим. Вы пишите "так как у moodle и так есть информация о том, сколько раз уже этот пользователь смотрел этот файл".  А где эту информацию можно смотреть? 

Возможно ли в мудл проверять на какой странице находится пользователь?  Так например, если это страница просмотра файла mod/resource/view.php?id=39 то файл отдавать функцией send_stored_file. Если это сам файл в браузере domen.ru/pluginfile.php/126/mod_resource/content/2/video.mp4  то не запускать функцию send_stored_file.  То есть, контролировать на какой странице находиться пользователь. Например есть ли что-то наподобие такой функции is_page('course'). 

Пробовал как-то ограничить это через права     

if (!has_capability('mod/resource:view', $context)) {

        return false;

   }

но нужного права на открытие файла mp4 в браузере не нашел. Можно ли в moodle создавать свои права? Роли я понял, что можно.

В ответ на Дмитрий Пименов

Re: Генерация одноразовых ссылок на файл

от Vadim Dvorovenko -
Изображение пользователя Developers Изображение пользователя Майнтейнер перевода

Дмитрий, Вы плохо себе представляете работу браузера и протокола http, вне зависимости от moodle. Каждый файл отдаётся http независимо, view.php - это один файл, pluginfile.php - другой, и сервер при отдаче pluginfile.php не знает, находится ли пользователь на странице view.php. Есть, конечно, http-заголовок referer, из которого можно это узнать, но его можно легко подделать, поэтому ориентироваться на него - не правильно, это можно использовать только дополнительный уровень защиты.

"так как у moodle и так есть информация о том, сколько раз уже этот пользователь смотрел этот файл".  А где эту информацию можно смотреть? Я имел в виду, что когда у вас пользователь открывает любую страницу moodle, в глобальной переменной USER есть его данные, в том числе логин и уникальный идентификатор базе данных. Каким именно образом вы будете хранить историю просмотров - уже ваше дело, как разработчика модуля. Но каждый раз, когда пользователь будет запрашивать этот файл в очередной раз, в функции имямодуля_pluginfile у вас будет информация об элементе курса, имени файла и пользователе - эти данных будет достаточно, чтобы понять, скачивал именно этот пользователь именно этот файл или нет, если вы правильно до этого сохранили факт просмотра.