diff --git a/actions/sharing b/actions/sharing new file mode 100644 index 000000000..a3dd88669 --- /dev/null +++ b/actions/sharing @@ -0,0 +1,102 @@ +#!/usr/bin/python3 +# -*- mode: python -*- +# +# This file is part of Plinth. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# + +""" +Configuration helper for the sharing module +""" + +import argparse +import os + +import augeas + + +def parse_arguments(): + parser = argparse.ArgumentParser() + subparsers = parser.add_subparsers(help='Sub command') + + subparsers.add_parser('add', help='Add a new share') + subparsers.add_parser('remove', help='Remove an existing share') + subparsers.add_parser('list', help='Remove an existing share') + + subparsers.required = True + return parser.parse_args() + + +def load_augeas(conf_file): + aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD + + augeas.Augeas.NO_MODL_AUTOLOAD) + aug.set('/augeas/load/Httpd/lens', 'Httpd.lns') + aug.set('/augeas/load/Httpd/incl[last() + 1]', conf_file) + aug.load() + + return aug + + +# TODO: Handle the error case scenarios +def subcommand_add(arguments): + share_url = arguments.url + share_path = arguments.path + share_user = arguments.user + + aug = load_augeas('/etc/apache2/sites-available/sharing.conf') + aug.defvar('conf', '/files/etc/apache2/sites-available/sharing.conf') + + if os.path.exists(share_path): + try: + aug.set('$conf/directive[last() + 1]', 'Alias') + aug.set('$conf/directive[last()]/arg[last() + 1]', share_url) + aug.set('$conf/directive[last()]/arg[last() + 1]', share_path) + + aug.set('$conf/Directory[last() + 1]') + aug.set('$conf/Directory[last()]/arg', share_path) + aug.set('$conf/Directory[last()]/directive[last() + 1]', 'Include') + aug.set('$conf/Directory[last()]/directive[last()]/arg', 'includes/freedombox-sharing.conf') + aug.set('$conf/Directory[last()]/directive[last() + 1]', 'Require') + aug.set('$conf/Directory[last()]/directive[last()]/arg', share_user) + except Exception: + pass + + +def subcommand_list(): + aug = load_augeas('/etc/apache2/sites-available/sharing.conf') + aug.defvar('conf', '/files/etc/apache2/sites-available/sharing.conf') + + path = '/files/etc/apache2/conf-available/sharing.conf/Directory' + list_of_shares = [] + for match in aug.match(path): + path = aug.get(match + '/arg') + for directive_name in aug.match(match + '/directive'): + if directive_name == 'Require': + user = aug.get(directive_name + '/arg') + list_of_shares.append(dict(path=path, user_group=user)) + return list_of_shares + + +def main(): + """Parse arguments and perform all duties""" + arguments = parse_arguments() + + subcommand = arguments.subcommand.replace('-', '_') + subcommand_method = globals()['subcommand_' + subcommand] + subcommand_method(arguments) + + +if __name__ == '__main__': + main() diff --git a/data/etc/apache2/conf-available/sharing.conf b/data/etc/apache2/conf-available/sharing.conf new file mode 100644 index 000000000..e69de29bb diff --git a/data/etc/apache2/includes/freedombox-sharing.conf b/data/etc/apache2/includes/freedombox-sharing.conf new file mode 100644 index 000000000..388435715 --- /dev/null +++ b/data/etc/apache2/includes/freedombox-sharing.conf @@ -0,0 +1 @@ +Options -FollowSymLinks \ No newline at end of file diff --git a/data/etc/plinth/modules-enabled/sharing b/data/etc/plinth/modules-enabled/sharing new file mode 100644 index 000000000..7972c57cb --- /dev/null +++ b/data/etc/plinth/modules-enabled/sharing @@ -0,0 +1 @@ +plinth.modules.sharing \ No newline at end of file diff --git a/plinth/modules/sharing/__init__.py b/plinth/modules/sharing/__init__.py new file mode 100644 index 000000000..597b24c2b --- /dev/null +++ b/plinth/modules/sharing/__init__.py @@ -0,0 +1,107 @@ +# +# This file is part of Plinth. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# + +""" +Plinth module to configure sharing. +""" +import os + +from django import forms +from django.template.response import TemplateResponse +from django.urls import reverse_lazy +from django.utils.translation import ugettext_lazy as _, ugettext_lazy + +from plinth import actions +from plinth.menu import main_menu +from plinth.modules.users import groups + +version = 1 + +name = _('Sharing') + +short_description = _('File Sharing') + +description = [ + _('Sharing allows you to share your content over web with a group of ' + 'users. Add the content you would like to share in the sharing app.'), + + _('Sharing app will be available from ' + '/sharing path on the web server.'), +] + +subsubmenu = [{'url': reverse_lazy('sharing:about'), + 'text': ugettext_lazy('About')}, + {'url': reverse_lazy('sharing:add_share'), + 'text': ugettext_lazy('Add share')}] + + +def init(): + """Initialize the module.""" + menu = main_menu.get('apps') + menu.add_urlname(name, 'glyphicon-share', 'sharing:about') + + +def index(request): + return TemplateResponse(request, 'about.html', + {'title': name, + 'description': description, + 'subsubmenu': subsubmenu}) + + +# TODO: handle the error case +def add_path_to_share(url, path, user_group): + if os.path.exists(path): + actions.superuser_run('sharing', options=['add', url, path, user_group]) + else: + pass + + +def share(request): + if request.method == 'POST': + form = AddShareForm(request.POST) + + if form.is_valid(): + path = form.cleaned_data['share_path'] + user_group = form.cleaned_data['user_group'] + share_url = 'share_' + path.split("/")[len(path.split("/")) - 1] + add_path_to_share(share_url, path, user_group) + + form = AddShareForm() + + else: + form = AddShareForm() + + return TemplateResponse(request, 'share.html', + {'title': name, + 'subsubmenu': subsubmenu, + 'form': form}) + + +class AddShareForm(forms.Form): + share_path = forms.CharField( + label=_('Add path'), + help_text=_('Add the path to the folder you want to share')) + + user_group = forms.ChoiceField( + required=False, + choices=groups, + label=_('User-group'), + initial=None) + + def __init__(self, *args, **kwargs): + super(forms.Form, self).__init__(*args, **kwargs) + return diff --git a/plinth/modules/sharing/templates/about.html b/plinth/modules/sharing/templates/about.html new file mode 100644 index 000000000..91e4bff4d --- /dev/null +++ b/plinth/modules/sharing/templates/about.html @@ -0,0 +1,25 @@ +{% extends "simple_service.html" %} +{% comment %} +# +# This file is part of Plinth. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +{% endcomment %} + +{% load i18n %} + +{% block configuration %} + +{% endblock %} diff --git a/plinth/modules/sharing/templates/share.html b/plinth/modules/sharing/templates/share.html new file mode 100644 index 000000000..ceb22ac11 --- /dev/null +++ b/plinth/modules/sharing/templates/share.html @@ -0,0 +1,36 @@ +{% extends "simple_service.html" %} +{% comment %} +# +# This file is part of Plinth. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +{% endcomment %} + +{% load bootstrap %} +{% load i18n %} + +{% block configuration %} + +
+ {% csrf_token %} + + {{ form|bootstrap }} + + +
+ + +{% endblock %} \ No newline at end of file diff --git a/plinth/modules/sharing/urls.py b/plinth/modules/sharing/urls.py new file mode 100644 index 000000000..4a85e3fe1 --- /dev/null +++ b/plinth/modules/sharing/urls.py @@ -0,0 +1,29 @@ +# +# This file is part of Plinth. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# + +""" +URLs for the sharing module. +""" + +from django.conf.urls import url + +from . import index, share + +urlpatterns = [ + url(r'^apps/sharing/$', index, name='about'), + url(r'^apps/sharing/add_share$', share, name='add_share'), +] \ No newline at end of file