Общий форум

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

 
Изображение пользователя Дмитрий Пименов
Генерация одноразовых ссылок на файл
 

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

Изображение пользователя Дмитрий Пименов
Re: Генерация одноразовых ссылок на файл
 
Это будет видео файл. стандартные возможности вставки в видео такой защиты не предусматривают. Какой тип плагина это будет исходя из http://docs.moodle.org/dev/Plugins ?
Изображение пользователя Vadim Dvorovenko
Re: Генерация одноразовых ссылок на файл
DevelopersМайнтейнер переводаТестер MoodleЭксперт по Moodle

Вам, скорее всего, потребуется 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()

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

Изображение пользователя Дмитрий Пименов
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 файле, которого там уже нет, то ссылка будет неправильной.


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

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

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

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

2. На основе случайных ключей: ссылки по тексту заменяются на внутренний редирект на стороне Moodle. Когда пользователь перешел на скрипт редиректа, он формирует одноразовый ключ и помещает его в таблицу одноразовых ключей (либо запрашивает одноразовый ключ от медиаархива), затем, присоединяет одноразовый ключ к URL и редиректит пользователя на него. Медиаархив проверяет наличие одноразового ключа в базе данных, срок его жизни, затем открывает пользователю доступ и удаляет ключ из базы данных.
Изображение пользователя Vadim Dvorovenko
Re: Генерация одноразовых ссылок на файл
DevelopersМайнтейнер переводаТестер MoodleЭксперт по Moodle

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

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

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

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

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

Изображение пользователя Дмитрий Пименов
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 создавать свои права? Роли я понял, что можно.

Изображение пользователя Vadim Dvorovenko
Re: Генерация одноразовых ссылок на файл
DevelopersМайнтейнер переводаТестер MoodleЭксперт по Moodle

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

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