Beispiel #1
0
class EjabberdForm(forms.Form):
    """Ejabberd configuration form."""
    MAM_enabled = forms.BooleanField(
        label=_('Enable Message Archive Management'), required=False,
        help_text=format_lazy(
            _('If enabled, your {box_name} will store chat message histories. '
              'This allows synchronization of conversations between multiple '
              'clients, and reading the history of a multi-user chat room. '
              'It depends on the client settings whether the histories are '
              'stored as plain text or encrypted.'), box_name=_(cfg.box_name)))

    enable_managed_turn = forms.BooleanField(
        label=_('Automatically manage audio/video call setup'), required=False,
        help_text=format_lazy(
            _('Configures the local <a href={coturn_url}>coturn</a> app as '
              'the STUN/TURN server for ejabberd. Disable this if you '
              'want to use a different STUN/TURN server.'),
            coturn_url=reverse_lazy('coturn:index')))

    # STUN/TURN server setup
    turn_uris = forms.CharField(
        label=_('STUN/TURN Server URIs'), required=False, strip=True,
        widget=forms.Textarea(attrs={'rows': 4}),
        help_text=_('List of public URIs of the STUN/TURN server, one on each '
                    'line.'), validators=[turn_uris_validator])

    shared_secret = forms.CharField(
        label=_('Shared Authentication Secret'), required=False, strip=True,
        help_text=_('Shared secret used to compute passwords for the '
                    'TURN server.'))

    def clean_turn_uris(self):
        """Normalize newlines in URIs."""
        data = self.cleaned_data['turn_uris']
        return '\n'.join([uri.strip() for uri in data.splitlines()])
Beispiel #2
0
class InternetConnectionTypeForm(forms.Form):
    """Form for type of public/private IP address ISP provides.

    Ask the user for what type of Internet connection they have. We store this
    information and use it suggest various setup options during the setup
    process and also later on when setting up apps.

    """
    internet_connection_type = forms.ChoiceField(
        label=_('Choose your internet connection type'),
        choices=[
            ('dynamic_public_ip',
             format_lazy(
                 _('I have a public IP address that may change over time'
                   '<p class="help-block">This means that devices on the '
                   'Internet can reach you when you are connected to the '
                   'Internet. Every time you connect to the Internet with '
                   'your Internet Service Provider (ISP), you may get a '
                   'different IP address, especially after some offline time. '
                   'Many ISPs offer this type of connectivity. If you have a '
                   'public IP address but are unsure if it changes over time '
                   'or not, it is safer to choose this option.</p>'),
                 allow_markup=True)),
            ('static_public_ip',
             format_lazy(
                 _('I have a public IP address that does not change over time '
                   '(recommended)'
                   '<p class="help-block">This means that devices on the '
                   'Internet can reach you when you are connected to the '
                   'Internet. Every time you connect to the Internet with '
                   'your Internet Service Provider (ISP), you always get the '
                   'same IP address. This is the most trouble-free setup for '
                   'many {box_name} services but very few ISPs offer this. '
                   'You may be able to get this service from your ISP by '
                   'making an additional payment.</p>'), box_name=cfg.box_name,
                 allow_markup=True)),
            ('private_ip',
             format_lazy(
                 _('I dont have a public IP address'
                   '<p class="help-block">This means that devices on the '
                   'Internet <b>can not</b> reach you when you are connected '
                   'to the Internet. Every time you connect to the Internet '
                   'with your Internet Service Provider (ISP), you get an IP '
                   'address that is only relevant for local networks. '
                   'Many ISPs offer this type of connectivity. This is the '
                   'most troublesome situation for hosting services at home. '
                   '{box_name} provides many workaround solutions but each '
                   'solution has some limitations.</p>'),
                 box_name=cfg.box_name, allow_markup=True)),
            ('unknown',
             format_lazy(
                 _('I do not know the type of connection my ISP provides '
                   '<p class="help-block">You will be suggested the most '
                   'conservative actions.</p>'), allow_markup=True)),
        ],
        required=True,
        widget=forms.RadioSelect,
    )
Beispiel #3
0
class ConfigurationForm(forms.Form):
    """Main system configuration form"""
    # See:
    # https://tools.ietf.org/html/rfc952
    # https://tools.ietf.org/html/rfc1035#section-2.3.1
    # https://tools.ietf.org/html/rfc1123#section-2
    # https://tools.ietf.org/html/rfc2181#section-11
    hostname = TrimmedCharField(
        label=ugettext_lazy('Hostname'),
        help_text=format_lazy(ugettext_lazy(
            'Hostname is the local name by which other devices on the local '
            'network can reach your {box_name}.  It must start and end with '
            'an alphabet or a digit and have as interior characters only '
            'alphabets, digits and hyphens.  Total length must be 63 '
            'characters or less.'),
                              box_name=ugettext_lazy(cfg.box_name)),
        validators=[
            validators.RegexValidator(HOSTNAME_REGEX,
                                      ugettext_lazy('Invalid hostname'))
        ])

    domainname = TrimmedCharField(
        label=ugettext_lazy('Domain Name'),
        help_text=format_lazy(ugettext_lazy(
            'Domain name is the global name by which other devices on the '
            'Internet can reach your {box_name}.  It must consist of labels '
            'separated by dots.  Each label must start and end with an '
            'alphabet or a digit and have as interior characters only '
            'alphabets, digits and hyphens.  Length of each label must be 63 '
            'characters or less.  Total length of domain name must be 253 '
            'characters or less.'),
                              box_name=ugettext_lazy(cfg.box_name)),
        required=False,
        validators=[
            validators.RegexValidator(
                r'^[a-zA-Z0-9]([-a-zA-Z0-9.]{,251}[a-zA-Z0-9])?$',
                ugettext_lazy('Invalid domain name')), domain_label_validator
        ])

    language = forms.ChoiceField(
        label=ugettext_lazy('Language'),
        help_text=ugettext_lazy(
            'Language for this web administration interface'),
        required=False)

    def __init__(self, *args, **kwargs):
        """Set limited language choices."""
        super().__init__(*args, **kwargs)
        languages = []
        for language_code, language_name in settings.LANGUAGES:
            locale_code = translation.to_locale(language_code)
            plinth_dir = os.path.dirname(plinth.__file__)
            if language_code == 'en' or os.path.exists(
                    os.path.join(plinth_dir, 'locale', locale_code)):
                languages.append((language_code, language_name))

        self.fields['language'].choices = languages
Beispiel #4
0
class ConfigurationForm(forms.Form):
    """Main system configuration form"""
    # See:
    # https://tools.ietf.org/html/rfc952
    # https://tools.ietf.org/html/rfc1035#section-2.3.1
    # https://tools.ietf.org/html/rfc1123#section-2
    # https://tools.ietf.org/html/rfc2181#section-11
    hostname = forms.CharField(
        label=gettext_lazy('Hostname'), help_text=format_lazy(
            gettext_lazy(
                'Hostname is the local name by which other devices on the '
                'local network can reach your {box_name}.  It must start and '
                'end with an alphabet or a digit and have as interior '
                'characters only alphabets, digits and hyphens.  Total '
                'length must be 63 characters or less.'),
            box_name=gettext_lazy(cfg.box_name)), validators=[
                validators.RegexValidator(HOSTNAME_REGEX,
                                          gettext_lazy('Invalid hostname'))
            ], strip=True)

    domainname = forms.CharField(
        label=gettext_lazy('Domain Name'), help_text=format_lazy(
            gettext_lazy(
                'Domain name is the global name by which other devices on the '
                'Internet can reach your {box_name}.  It must consist of '
                'labels separated by dots.  Each label must start and end '
                'with an alphabet or a digit and have as interior characters '
                'only alphabets, digits and hyphens.  Length of each label '
                'must be 63 characters or less.  Total length of domain name '
                'must be 253 characters or less.'),
            box_name=gettext_lazy(cfg.box_name)), required=False, validators=[
                validators.RegexValidator(
                    r'^[a-zA-Z0-9]([-a-zA-Z0-9.]{,251}[a-zA-Z0-9])?$',
                    gettext_lazy('Invalid domain name')),
                domain_label_validator
            ], strip=True)

    homepage = forms.ChoiceField(
        label=gettext_lazy('Webserver Home Page'), help_text=format_lazy(
            gettext_lazy(
                'Choose the default page that must be served when '
                'someone visits your {box_name} on the web. A typical use '
                'case is to set your blog or wiki as the home page when '
                'someone visits the domain name. Note that once the home '
                'page is set to something other than {box_name} Service '
                '(Plinth), your users must explicitly type /plinth or '
                '/freedombox to reach {box_name} Service (Plinth).'),
            box_name=gettext_lazy(cfg.box_name)), required=False,
        choices=get_homepage_choices)

    advanced_mode = forms.BooleanField(
        label=gettext_lazy('Show advanced apps and features'), required=False,
        help_text=gettext_lazy(
            'Show apps and features that require more technical '
            'knowledge.'))
class RouterConfigurationForm(forms.Form):
    """Form to suggest how to configure a router.

    Suggest depending on wan connectivity/specific setup. The choice will
    affect future suggestions during the setup process and other apps.

    """
    router_config = forms.ChoiceField(
        label=_('Preferred router configuration'),
        choices=[
            (
                'dmz',
                format_lazy(_(
                    'Use DMZ feature to forward all traffic (recommended) '
                    '<p class="help-block">Most routers provide a '
                    'configuration setting called DMZ. This will allow the '
                    'router to forward all incoming traffic from the '
                    'Internet to a single IP address such as the '
                    '{box_name}\'s IP address. First remember to configure '
                    'a static local IP address for your {box_name} in your '
                    'router\'s configuration.</p>'),
                            box_name=cfg.box_name,
                            allow_markup=True),
            ),
            ('port_forwarding',
             format_lazy(_(
                 'Forward specific traffic as needed by each '
                 'application '
                 '<p class="help-block">You may alternatively choose to '
                 'forward only specific traffic to your {box_name}. '
                 'This is ideal if you have other servers like '
                 '{box_name} in your network or if your router does not '
                 'support DMZ feature. All applications that provide a '
                 'web interface need you to forward traffic from ports '
                 '80 and 443 to work. Each of the other applications '
                 'will suggest which port(s) need to be forwarded '
                 'for that application to work.</p>'),
                         box_name=cfg.box_name,
                         allow_markup=True)),
            ('not_configured',
             format_lazy(_('Router is currently unconfigured '
                           '<p class="help-block">Choose this if you have not '
                           'configured or are unable to configure the router '
                           'currently and wish to be reminded later. Some of '
                           'the other configuration steps may fail.</p>'),
                         allow_markup=True)),
        ],
        required=True,
        widget=forms.RadioSelect,
    )
Beispiel #6
0
class MatrixSynapseForm(forms.Form):
    enable_public_registration = forms.BooleanField(
        label=_('Enable Public Registration'), required=False, help_text=_(
            'Enabling public registration means that anyone on the Internet '
            'can register a new account on your Matrix server. Disable this '
            'if you only want existing users to be able to use it.'))

    enable_managed_turn = forms.BooleanField(
        label=_('Automatically manage audio/video call setup'), required=False,
        help_text=format_lazy(
            _('Configures the local <a href={coturn_url}>coturn</a> app as '
              'the STUN/TURN server for Matrix Synapse. Disable this if you '
              'want to use a different STUN/TURN server.'),
            coturn_url=reverse_lazy('coturn:index')))

    # STUN/TURN server setup
    turn_uris = forms.CharField(
        label=_('STUN/TURN Server URIs'), required=False, strip=True,
        widget=forms.Textarea(attrs={'rows': 4}),
        help_text=_('List of public URIs of the STUN/TURN server, one on each '
                    'line.'), validators=[turn_uris_validator])

    shared_secret = forms.CharField(
        label=_('Shared Authentication Secret'), required=False, strip=True,
        help_text=_('Shared secret used to compute passwords for the '
                    'TURN server.'))

    def clean_turn_uris(self):
        """Normalize newlines in URIs."""
        data = self.cleaned_data['turn_uris']
        return '\n'.join([uri.strip() for uri in data.splitlines()])
Beispiel #7
0
def warn_about_low_disk_space(request):
    """Warn about insufficient space on root partition."""
    if not is_user_admin(request, cached=True):
        return

    disks = storage.get_disks()
    list_root = [disk for disk in disks if disk['mountpoint'] == '/']
    if not list_root:
        logger.error('Error getting information about root partition.')
        return

    percent_used = list_root[0]['percent_used']
    size_bytes = list_root[0]['size']
    free_bytes = list_root[0]['free']
    free_gib = free_bytes / (1024 ** 3)

    message = format_lazy(
        # Translators: xgettext:no-python-format
        _('Warning: Low space on system partition ({percent_used}% used, '
          '{free_space} free).'),
        percent_used=percent_used,
        free_space=storage.format_bytes(free_bytes))

    if percent_used > 90 or free_gib < 1:
        messages.error(request, message)
    elif percent_used > 75 or free_gib < 2:
        messages.warning(request, message)
Beispiel #8
0
class EncryptedBackupsMixin(forms.Form):
    """Form to add a new backup repository."""
    encryption = forms.ChoiceField(
        label=_('Encryption'),
        help_text=format_lazy(
            _('"Key in Repository" means that a '
              'password-protected key is stored with the backup.')),
        choices=[('repokey', _('Key in Repository')), ('none', _('None'))])
    encryption_passphrase = forms.CharField(
        label=_('Passphrase'),
        help_text=_('Passphrase; Only needed when using encryption.'),
        widget=forms.PasswordInput(),
        required=False)
    confirm_encryption_passphrase = forms.CharField(
        label=_('Confirm Passphrase'),
        help_text=_('Repeat the passphrase.'),
        widget=forms.PasswordInput(),
        required=False)

    def clean(self):
        super().clean()
        passphrase = self.cleaned_data.get('encryption_passphrase')
        confirm_passphrase = self.cleaned_data.get(
            'confirm_encryption_passphrase')

        if passphrase != confirm_passphrase:
            raise forms.ValidationError(
                _('The entered encryption passphrases do not match'))

        if self.cleaned_data.get('encryption') != 'none' and not passphrase:
            raise forms.ValidationError(
                _('Passphrase is needed for encryption.'))

        return self.cleaned_data
Beispiel #9
0
    def __init__(self):
        """Create components for the app."""
        super().__init__()

        self.groups = {'vpn': _('Connect to VPN services')}

        info = app_module.Info(app_id=self.app_id,
                               version=self._version,
                               name=_('OpenVPN'),
                               icon_filename='openvpn',
                               short_description=_('Virtual Private Network'),
                               description=_description,
                               manual_page='OpenVPN',
                               clients=manifest.clients)
        self.add(info)

        menu_item = menu.Menu('menu-openvpn',
                              info.name,
                              info.short_description,
                              info.icon_filename,
                              'openvpn:index',
                              parent_url_name='apps')
        self.add(menu_item)

        download_profile = \
            format_lazy(_('<a class="btn btn-primary btn-sm" href="{link}">'
                          'Download Profile</a>'),
                        link=reverse_lazy('openvpn:profile'))
        shortcut = frontpage.Shortcut(
            'shortcut-openvpn',
            info.name,
            short_description=info.short_description,
            icon=info.icon_filename,
            description=info.description + [download_profile],
            configure_url=reverse_lazy('openvpn:index'),
            login_required=True,
            allowed_groups=['vpn'])
        self.add(shortcut)

        packages = Packages('packages-openvpn', ['openvpn', 'easy-rsa'])
        self.add(packages)

        firewall = Firewall('firewall-openvpn',
                            info.name,
                            ports=['openvpn'],
                            is_external=True)
        self.add(firewall)

        daemon = Daemon('daemon-openvpn',
                        'openvpn-server@freedombox',
                        listen_ports=[(1194, 'udp4'), (1194, 'udp6')])
        self.add(daemon)

        users_and_groups = UsersAndGroups('users-and-groups-openvpn',
                                          groups=self.groups)
        self.add(users_and_groups)

        backup_restore = BackupRestore('backup-restore-openvpn',
                                       **manifest.backup)
        self.add(backup_restore)
Beispiel #10
0
def warn_about_low_disk_space(request):
    """Warn about insufficient space on root partition."""
    if not is_user_admin(request, cached=True):
        return

    disks = storage.get_disks()
    list_root = [disk for disk in disks if disk['mountpoint'] == '/']
    if not list_root:
        logger.error('Error getting information about root partition.')
        return

    percent_used = list_root[0]['percent_used']
    size_bytes = list_root[0]['size']
    free_bytes = list_root[0]['free']
    free_gib = free_bytes / (1024**3)

    message = format_lazy(
        # Translators: xgettext:no-python-format
        _('Warning: Low space on system partition ({percent_used}% used, '
          '{free_space} free).'),
        percent_used=percent_used,
        free_space=storage.format_bytes(free_bytes))

    if percent_used > 90 or free_gib < 1:
        messages.error(request, message)
    elif percent_used > 75 or free_gib < 2:
        messages.warning(request, message)
Beispiel #11
0
def warn_about_low_disk_space(request):
    """Warn about insufficient space on root partition."""
    if not is_user_admin(request, cached=True):
        return

    disks = disks_module.get_disks()
    list_root = [disk for disk in disks if disk['mountpoint'] == '/']
    if not list_root:
        logger.error('Error getting information about root partition.')
        return

    perc_used = list_root[0]['percentage_used']
    size_bytes = _interpret_size_string(list_root[0]['size'])
    free_bytes = size_bytes * (100 - perc_used) / 100

    message = format_lazy(_(
        'Warning: Low space on system partition ({percent_used}% used, '
        '{free_space} free).'),
                          percent_used=perc_used,
                          free_space=_format_bytes(free_bytes))

    free_gib = free_bytes / (1024**3)
    if perc_used > 90 or free_gib < 1:
        messages.error(request, message)
    elif perc_used > 75 or free_gib < 2:
        messages.warning(request, message)
Beispiel #12
0
    def __init__(self):
        """Create components for the app."""
        super().__init__()

        info = app_module.Info(app_id=self.app_id,
                               version=version,
                               is_essential=is_essential)
        self.add(info)

        web_server_ports = Firewall('firewall-web',
                                    _('Web Server'),
                                    ports=['http', 'https'],
                                    is_external=True)
        self.add(web_server_ports)

        freedombox_ports = Firewall('firewall-plinth',
                                    format_lazy(
                                        _('{box_name} Web Interface (Plinth)'),
                                        box_name=_(cfg.box_name)),
                                    ports=['http', 'https'],
                                    is_external=True)
        self.add(freedombox_ports)

        letsencrypt = LetsEncrypt('letsencrypt-apache',
                                  domains='*',
                                  daemons=[managed_services[0]])
        self.add(letsencrypt)

        daemon = Daemon('daemon-apache', managed_services[0])
        self.add(daemon)
Beispiel #13
0
class AddRepositoryForm(EncryptedBackupsMixin, forms.Form):
    """Form to create a new backups repository on a disk."""
    disk = forms.ChoiceField(
        label=_('Select Disk or Partition'), help_text=format_lazy(
            _('Backups will be stored in the directory FreedomBoxBackups')),
        choices=get_disk_choices)

    field_order = ['disk'] + encryption_fields
Beispiel #14
0
def add_shortcut():
    """Add shortcut in frontpage."""
    download_profile = \
        format_lazy(_('<a class="btn btn-primary btn-sm" href="{link}">'
                      'Download Profile</a>'),
                    link=reverse_lazy('openvpn:profile'))
    frontpage.add_shortcut(
        'openvpn', name, short_description=short_description,
        details=description + [download_profile],
        configure_url=reverse_lazy('openvpn:index'), login_required=True)
Beispiel #15
0
class NetworkTopologyForm(forms.Form):
    """Form to ask the user for network topology.

    That is how the FreedomBox is connected to the internal network topology.
    Store this information for future suggestions when setting up services.

    """
    network_topology = forms.ChoiceField(
        label=format_lazy(
            _('Specify how your {box_name} is connected to your network'),
            box_name=cfg.box_name),
        required=True,
        widget=forms.RadioSelect,
        choices=[
            ('to_router',
             format_lazy(_(
                 'Connected to a router '
                 '<p class="help-block">Your {box_name} gets its Internet '
                 'connection from your router via Wi-Fi or Ethernet cable. '
                 'This is a typical home setup.</p>'),
                         box_name=cfg.box_name,
                         allow_markup=True)),
            ('as_router',
             format_lazy(_(
                 '{box_name} is your router '
                 '<p class="help-block">Your {box_name} has multiple '
                 'network interfaces such as multiple Ethernet ports or '
                 'a Wi-Fi adapter. {box_name} is directly connected to the '
                 'Internet and all your devices connect to {box_name} '
                 'for their Internet connectivity.</p>'),
                         box_name=cfg.box_name,
                         allow_markup=True)),
            ('direct',
             format_lazy(_(
                 'Directly connected to the Internet '
                 '<p class="help-block">Your Internet connection is '
                 'directly attached to your {box_name} and there are no '
                 'other devices on the network. This can happen on '
                 'community or cloud setups.</p>'),
                         box_name=cfg.box_name,
                         allow_markup=True)),
        ],
    )
Beispiel #16
0
class RoundcubeForm(forms.Form):
    """Roundcube configuration form."""
    local_only = forms.BooleanField(
        label=_('Use only the local mail server'),
        help_text=format_lazy(_(
            'When enabled, text box for server input is removed from login '
            'page and users can only read and send mails from this '
            '{box_name}.'),
                              box_name=_(cfg.box_name)),
        required=False)
Beispiel #17
0
def add_shortcut():
    """Add shortcut in frontpage."""
    download_profile = \
        format_lazy(_('<a class="btn btn-primary btn-sm" href="{link}">'
                      'Download Profile</a>'),
                    link=reverse_lazy('openvpn:profile'))
    frontpage.add_shortcut('openvpn',
                           title,
                           details=description + [download_profile],
                           configure_url=reverse_lazy('openvpn:index'),
                           login_required=True)
Beispiel #18
0
class EjabberdForm(plinthForms.ServiceForm):
    """Ejabberd configuration form."""
    MAM_enabled = djangoForms.BooleanField(
        label=_('Enable Message Archive Management'),
        required=False,
        help_text=format_lazy(_(
            'If enabled, your {box_name} will store chat message histories. '
            'This allows synchronization of conversations between multiple '
            'clients, and reading the history of a multi-user chat room. '
            'It depends on the client settings whether the histories are '
            'stored as plain text or encrypted.'),
                              box_name=_(cfg.box_name)))
Beispiel #19
0
def get_homepage_choices():
    """Return list of drop down choices for home page."""
    shortcuts = frontpage.Shortcut.list(web_apps_only=True)
    shortcut_choices = [(shortcut.component_id, shortcut.name)
                        for shortcut in shortcuts if shortcut.is_enabled()]
    uws_choices = \
        [(home_page_url2scid(url),
         format_lazy(ugettext_lazy("{user}'s website"), user=user))
         for user, url in get_users_with_website().items()]
    apache_default = ('apache-default', _('Apache Default'))
    plinth = ('plinth', _('FreedomBox Service (Plinth)'))
    return [apache_default, plinth] + uws_choices + shortcut_choices
Beispiel #20
0
def init():
    """Register some misc. services that don't fit elsewhere."""

    Service('http', _('Web Server'), ['http'], is_external=True, enabled=True)
    Service('https', _('Web Server over Secure Socket Layer'), ['https'],
            is_external=True, enabled=True)
    Service('ssh', _('Secure Shell (SSH) Server'), ['ssh'], is_external=True,
            enabled=True)
    Service('plinth',
            format_lazy(_('{box_name} Web Interface (Plinth)'),
                        box_name=_(cfg.box_name)),
            ['https'], is_external=True, enabled=True)
Beispiel #21
0
def init():
    """Register some misc. services that don't fit elsewhere."""

    Service("http", _("Web Server"), ports=["http"], is_external=True, is_enabled=True)
    Service("https", _("Web Server over Secure Socket Layer"), ports=["https"], is_external=True, is_enabled=True)
    Service("ssh", _("Secure Shell (SSH) Server"), ports=["ssh"], is_external=True, is_enabled=True)
    Service(
        "plinth",
        format_lazy(_("{box_name} Web Interface (Plinth)"), box_name=_(cfg.box_name)),
        ports=["https"],
        is_external=True,
        is_enabled=True,
    )
Beispiel #22
0
class RootBorgRepository(BaseBorgRepository):
    """Borg repository on the root filesystem."""
    UUID = 'root'
    PATH = '/var/lib/freedombox/borgbackup'

    storage_type = 'root'
    name = format_lazy(_('{box_name} storage'), box_name=cfg.box_name)
    borg_path = PATH
    sort_order = 10
    is_mounted = True

    def __init__(self, credentials=None):
        """Initialize the repository object."""
        super().__init__(self.PATH, credentials, self.UUID)
Beispiel #23
0
class ConfigurationForm(forms.Form):
    """Main system configuration form"""
    # See:
    # https://tools.ietf.org/html/rfc952
    # https://tools.ietf.org/html/rfc1035#section-2.3.1
    # https://tools.ietf.org/html/rfc1123#section-2
    # https://tools.ietf.org/html/rfc2181#section-11
    hostname = TrimmedCharField(
        label=ugettext_lazy('Hostname'),
        help_text=format_lazy(ugettext_lazy(
            'Hostname is the local name by which other devices on the local '
            'network can reach your {box_name}.  It must start and end with '
            'an alphabet or a digit and have as interior characters only '
            'alphabets, digits and hyphens.  Total length must be 63 '
            'characters or less.'), box_name=ugettext_lazy(cfg.box_name)),
        validators=[
            validators.RegexValidator(
                HOSTNAME_REGEX,
                ugettext_lazy('Invalid hostname'))])

    domainname = TrimmedCharField(
        label=ugettext_lazy('Domain Name'),
        help_text=format_lazy(ugettext_lazy(
            'Domain name is the global name by which other devices on the '
            'Internet can reach your {box_name}.  It must consist of labels '
            'separated by dots.  Each label must start and end with an '
            'alphabet or a digit and have as interior characters only '
            'alphabets, digits and hyphens.  Length of each label must be 63 '
            'characters or less.  Total length of domain name must be 253 '
            'characters or less.'), box_name=ugettext_lazy(cfg.box_name)),
        required=False,
        validators=[
            validators.RegexValidator(
                r'^[a-zA-Z0-9]([-a-zA-Z0-9.]{,251}[a-zA-Z0-9])?$',
                ugettext_lazy('Invalid domain name')),
            domain_label_validator])
Beispiel #24
0
class TorForm(forms.Form):  # pylint: disable=W0232
    """Tor configuration form."""
    enabled = forms.BooleanField(
        label=_('Enable Tor'),
        required=False)
    relay_enabled = forms.BooleanField(
        label=_('Enable Tor relay'),
        required=False,
        help_text=format_lazy(_(
            'When enabled, your {box_name} will run a Tor relay and donate '
            'bandwidth to the Tor network. Do this if you have more than '
            '2 megabits/s of upload and download bandwidth.'),
                              box_name=_(cfg.box_name)))
    bridge_relay_enabled = forms.BooleanField(
        label=_('Enable Tor bridge relay'),
        required=False,
        help_text=format_lazy(_(
            'When enabled, relay information is published in the Tor bridge '
            'database instead of public Tor relay database making it harder '
            'to censor this node. This helps others circumvent censorship.'),
                              box_name=_(cfg.box_name)))
    hs_enabled = forms.BooleanField(
        label=_('Enable Tor Hidden Service'),
        required=False,
        help_text=format_lazy(_(
            'A hidden service will allow {box_name} to provide selected '
            'services (such as wiki or chat) without revealing its '
            'location. Do not use this for strong anonymity yet.'),
                              box_name=_(cfg.box_name)))
    apt_transport_tor_enabled = forms.BooleanField(
        label=_('Download software packages over Tor'),
        required=False,
        help_text=_('When enabled, software will be downloaded over the Tor '
                    'network for installations and upgrades. This adds a '
                    'degree of privacy and security during software '
                    'downloads.'))
Beispiel #25
0
    def __init__(self):
        """Create components for the app."""
        super().__init__()
        info = app_module.Info(app_id=self.app_id,
                               version=version,
                               name=_('OpenVPN'),
                               icon_filename='openvpn',
                               short_description=_('Virtual Private Network'),
                               description=_description,
                               manual_page='OpenVPN',
                               clients=clients)
        self.add(info)

        menu_item = menu.Menu('menu-openvpn',
                              info.name,
                              info.short_description,
                              info.icon_filename,
                              'openvpn:index',
                              parent_url_name='apps')
        self.add(menu_item)

        download_profile = \
            format_lazy(_('<a class="btn btn-primary btn-sm" href="{link}">'
                          'Download Profile</a>'),
                        link=reverse_lazy('openvpn:profile'))
        shortcut = frontpage.Shortcut(
            'shortcut-openvpn',
            info.name,
            short_description=info.short_description,
            icon=info.icon_filename,
            description=info.description + [download_profile],
            configure_url=reverse_lazy('openvpn:index'),
            login_required=True)
        self.add(shortcut)

        firewall = Firewall('firewall-openvpn',
                            info.name,
                            ports=['openvpn'],
                            is_external=True)
        self.add(firewall)

        daemon = Daemon('daemon-openvpn',
                        managed_services[0],
                        listen_ports=[(1194, 'udp4'), (1194, 'udp6')])
        self.add(daemon)
Beispiel #26
0
class TorForm(forms.Form):  # pylint: disable=W0232
    """Tor configuration form."""
    enabled = forms.BooleanField(label=_('Enable Tor'), required=False)
    hs_enabled = forms.BooleanField(
        label=_('Enable Tor Hidden Service'),
        required=False,
        help_text=format_lazy(_(
            'A hidden service will allow {box_name} to provide selected '
            'services (such as ownCloud or chat) without revealing its '
            'location.'),
                              box_name=_(cfg.box_name)))
    apt_transport_tor_enabled = forms.BooleanField(
        label=_('Download software packages over Tor'),
        required=False,
        help_text=_('When enabled, software will be downloaded over the Tor '
                    'network for installations and upgrades. This adds a '
                    'degree of privacy and security during software '
                    'downloads.'))
Beispiel #27
0
def init():
    """Register some misc. services that don't fit elsewhere."""
    Service('http',
            _('Web Server'),
            ports=['http'],
            is_external=True,
            is_enabled=True)
    Service('https',
            _('Web Server over Secure Socket Layer'),
            ports=['https'],
            is_external=True,
            is_enabled=True)
    Service('plinth',
            format_lazy(_('{box_name} Web Interface (Plinth)'),
                        box_name=_(cfg.box_name)),
            ports=['https'],
            is_external=True,
            is_enabled=True)
Beispiel #28
0
    def add_urlname(self,
                    name,
                    icon,
                    urlname,
                    short_description="",
                    order=50,
                    url_args=None,
                    url_kwargs=None):
        """Add a named URL to the menu (via add_item).

        url_args and url_kwargs will be passed on to Django reverse().

        """
        if short_description:
            label = format_lazy('{0} ({1})', short_description, name)
        else:
            label = name
        url = reverse_lazy(urlname, args=url_args, kwargs=url_kwargs)
        return self.add_item(label, icon, url, order)
Beispiel #29
0
    def _parse_progress(self, line):
        """Parse the apt-get process output line.

        See README.progress-reporting in apt source code.
        """
        parts = line.split(':')
        if len(parts) < 4:
            return

        status_map = {
            'pmstatus':
            ugettext_lazy('installing'),
            'dlstatus':
            ugettext_lazy('downloading'),
            'media-change':
            ugettext_lazy('media change'),
            'pmconffile':
            format_lazy(ugettext_lazy('configuration file: {file}'),
                        file=parts[1]),
        }
        self.status_string = status_map.get(parts[0], '')
        self.percentage = int(float(parts[2]))
Beispiel #30
0
    def __init__(self):
        """Create components for the app."""
        super().__init__()

        info = app_module.Info(app_id=self.app_id,
                               version=self._version,
                               is_essential=True,
                               name=_('Apache HTTP Server'))
        self.add(info)

        packages = Packages('packages-apache', [
            'apache2', 'php-fpm', 'ssl-cert', 'uwsgi', 'uwsgi-plugin-python3'
        ])
        self.add(packages)

        web_server_ports = Firewall('firewall-web',
                                    _('Web Server'),
                                    ports=['http', 'https'],
                                    is_external=True)
        self.add(web_server_ports)

        freedombox_ports = Firewall('firewall-plinth',
                                    format_lazy(
                                        _('{box_name} Web Interface (Plinth)'),
                                        box_name=_(cfg.box_name)),
                                    ports=['http', 'https'],
                                    is_external=True)
        self.add(freedombox_ports)

        letsencrypt = LetsEncrypt('letsencrypt-apache',
                                  domains='*',
                                  daemons=['apache2'])
        self.add(letsencrypt)

        daemon = Daemon('daemon-apache', 'apache2')
        self.add(daemon)

        daemon = RelatedDaemon('related-daemon-apache', 'uwsgi')
        self.add(daemon)
Beispiel #31
0
from django.utils.translation import ugettext_lazy as _

from plinth.clients import store_url, validate
from plinth.modules import diaspora
from plinth.utils import format_lazy

clients = validate([{
    'name':
        _('dandelion*'),
    'description':
        _('It is an unofficial webview based client for the '
          'community-run, distributed social network diaspora*'),
    'platforms': [{
        'type': 'store',
        'os': 'android',
        'store_name': 'f-droid',
        'url': store_url('f-droid', 'com.github.dfa.diaspora_android'),
    }]
}, {
    'name':
        _('diaspora*'),
    'platforms': [{
        'type':
            'web',
        'url':
            format_lazy('https://diaspora.{host}',
                        host=diaspora.get_configured_domain_name() if
                        diaspora.is_setup() else "<please-setup-domain-name>")
    }]
}])
Beispiel #32
0
short_description = _('Socks5 Proxy')

service = None

managed_services = ['shadowsocks-libev-local@freedombox']

managed_packages = ['shadowsocks-libev']

description = [
    _('Shadowsocks is a lightweight and secure SOCKS5 proxy, designed to '
      'protect your Internet traffic. It can be used to bypass Internet '
      'filtering and censorship.'),
    format_lazy(
        _('Your {box_name} can run a Shadowsocks client, that can connect to '
          'a Shadowsocks server. It will also run a SOCKS5 proxy. Local '
          'devices can connect to this proxy, and their data will be '
          'encrypted and proxied through the Shadowsocks server.'),
        box_name=_(cfg.box_name)),
    _('To use Shadowsocks after setup, set the SOCKS5 proxy URL in your '
      'device, browser or application to http://freedombox_address:1080/')
]


def init():
    """Intialize the module."""
    menu = main_menu.get('apps')
    menu.add_urlname(name, 'glyphicon-send', 'shadowsocks:index',
                     short_description)

    global service
    setup_helper = globals()['setup_helper']
Beispiel #33
0
# pylint: disable=C0103

version = 1

is_essential = True

depends = ['system']

title = _('Service Discovery')

description = [
    format_lazy(
        _('Service discovery allows other devices on the network to '
          'discover your {box_name} and services running on it.  It '
          'also allows {box_name} to discover other devices and '
          'services running on your local network.  Service discovery is '
          'not essential and works only on internal networks.  It may be '
          'disabled to improve security especially when connecting to a '
          'hostile local network.'), box_name=_(cfg.box_name))
]

service = None


def init():
    """Intialize the service discovery module."""
    menu = cfg.main_menu.get('system:index')
    menu.add_urlname(title, 'glyphicon-lamp', 'avahi:index', 950)

    global service  # pylint: disable=W0603
    service = service_module.Service(
Beispiel #34
0
managed_services = ['minetest-server']

managed_packages = ['minetest-server', 'minetest-mod-advspawning',
                    'minetest-mod-animalmaterials', 'minetest-mod-animals',
                    'minetest-mod-mesecons', 'minetest-mod-mobf-core',
                    'minetest-mod-mobf-trap', 'minetest-mod-moreblocks',
                    'minetest-mod-nether', 'minetest-mod-torches']

name = _('Minetest')

short_description = _('Block Sandbox')

description = [
    format_lazy(
        _('Minetest is a multiplayer infinite-world block sandbox. This '
          'module enables the Minetest server to be run on this '
          '{box_name}, on the default port (30000). To connect to the server, '
          'a <a href="http://www.minetest.net/downloads/">Minetest client</a> '
          'is needed.'), box_name=_(cfg.box_name)),
]

clients = clients

reserved_usernames = ['Debian-minetest']

CONFIG_FILE = '/etc/minetest/minetest.conf'
AUG_PATH = '/files' + CONFIG_FILE + '/.anon'


def init():
    """Initialize the module."""
    menu = main_menu.get('apps')
Beispiel #35
0
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#

"""
Plinth module for configuring Shadowsocks.
"""

from django import forms
from django.utils.translation import ugettext_lazy as _

from plinth.forms import ServiceForm
from plinth.utils import format_lazy

METHODS = [
    ('chacha20-ietf-poly1305',
     format_lazy('chacha20-ietf-poly1305 ({})', _('Recommended'))),
    ('aes-256-gcm', format_lazy('aes-256-gcm ({})', _('Recommended'))),
    ('aes-192-gcm', 'aes-192-gcm'),
    ('aes-128-gcm', 'aes-128-gcm'),
    ('aes-128-ctr', 'aes-128-ctr'),
    ('aes-192-ctr', 'aes-192-ctr'),
    ('aes-256-ctr', 'aes-256-ctr'),
    ('aes-128-cfb', 'aes-128-cfb'),
    ('aes-192-cfb', 'aes-192-cfb'),
    ('aes-256-cfb', 'aes-256-cfb'),
    ('camellia-128-cfb', 'camellia-128-cfb'),
    ('camellia-192-cfb', 'camellia-192-cfb'),
    ('camellia-256-cfb', 'camellia-256-cfb'),
    ('chacha20-ietf', 'chacha20-ietf')
]
Beispiel #36
0
managed_packages = ['syncthing']

name = _('Syncthing')

short_description = _('File Synchronization')

description = [
    _('Syncthing is an application to synchronize files across multiple '
      'devices, e.g. your desktop computer and mobile phone.  Creation, '
      'modification, or deletion of files on one device will be automatically '
      'replicated on all other devices that also run Syncthing.'),
    format_lazy(
        _('Running Syncthing on {box_name} provides an extra synchronization '
          'point for your data that is available most of the time, allowing '
          'your devices to synchronize more often.  {box_name} runs a single '
          'instance of Syncthing that may be used by multiple users.  Each '
          'user\'s set of devices may be synchronized with a distinct set of '
          'folders.  The web interface on {box_name} is only available for '
          'users belonging to the "admin" group.'), box_name=_(cfg.box_name)),
    _('When enabled, Syncthing\'s web interface will be available from '
      '<a href="/syncthing/">/syncthing</a>.  Desktop and mobile clients are '
      'also <a href="https://syncthing.net/">available</a>.'),
]

clients = clients

group = ('syncthing', _('Administer Syncthing application'))

service = None

Beispiel #37
0
managed_services = ['ejabberd']

managed_packages = ['ejabberd']

name = _('ejabberd')

short_description = _('Chat Server')

description = [
    _('XMPP is an open and standardized communication protocol. Here '
      'you can run and configure your XMPP server, called ejabberd.'),

    format_lazy(
        _('To actually communicate, you can use the <a href="/plinth/apps/'
          'jsxc">web client</a> or any other <a href=\'https://xmpp.org/'
          'software/clients\' target=\'_blank\'>XMPP client</a>. '
          'When enabled, ejabberd can be accessed by any <a href="/plinth/sys'
          '/users">user with a {box_name} login</a>.'),
        box_name=_(cfg.box_name))
]

clients = clients

reserved_usernames = ['ejabberd']

service = None

logger = logging.getLogger(__name__)


def init():
Beispiel #38
0
name = _('diaspora*')

short_description = _('Federated Social Network')

service = None

managed_services = ['diaspora']

managed_packages = ['diaspora']

description = [
    _('diaspora* is a decentralized social network where you can store '
      'and control your own data.'),
    format_lazy(
        'When enabled, the diaspora* pod will be available from '
        '<a href="https://diaspora.{host}">diaspora.{host}</a> path on the '
        'web server.'.format(host=get_configured_domain_name()) if is_setup()
        else 'Please register a domain name for your FreedomBox to be able to'
        ' federate with other diaspora* pods.')
]

from .manifest import clients  # isort:skip
clients = clients


def init():
    """Initialize the Diaspora module."""
    menu = main_menu.get('apps')
    menu.add_urlname(name, 'glyphicon-thumbs-up', 'diaspora:index',
                     short_description)

    global service
Beispiel #39
0
version = 1

depends = ['apps']

managed_services = ['node-restore']

managed_packages = ['node-restore']

title = _('Unhosted Storage \n (reStore)')

description = [
    format_lazy(
        _('reStore is a server for <a href=\'https://unhosted.org/\'>'
          'unhosted</a> web applications.  The idea is to uncouple web '
          'applications from data.  No matter where a web application is '
          'served from, the data can be stored on an unhosted storage '
          'server of user\'s choice.  With reStore, your {box_name} becomes '
          'your unhosted storage server.'), box_name=_(cfg.box_name)),

    _('You can create and edit accounts in the '
      '<a href=\'/restore/\'>reStore web-interface</a>.')
]

service = None


def init():
    """Initialize the reStore module."""
    menu = cfg.main_menu.get('apps:index')
    menu.add_urlname(title, 'glyphicon-hdd', 'restore:index')
Beispiel #40
0
# SPDX-License-Identifier: AGPL-3.0-or-later
"""
FreedomBox app for configuring Shadowsocks.
"""

from django import forms
from django.utils.translation import gettext_lazy as _

from plinth.utils import format_lazy

METHODS = [('chacha20-ietf-poly1305',
            format_lazy('chacha20-ietf-poly1305 ({})', _('Recommended'))),
           ('aes-256-gcm', format_lazy('aes-256-gcm ({})', _('Recommended'))),
           ('aes-192-gcm', 'aes-192-gcm'), ('aes-128-gcm', 'aes-128-gcm'),
           ('aes-128-ctr', 'aes-128-ctr'), ('aes-192-ctr', 'aes-192-ctr'),
           ('aes-256-ctr', 'aes-256-ctr'), ('aes-128-cfb', 'aes-128-cfb'),
           ('aes-192-cfb', 'aes-192-cfb'), ('aes-256-cfb', 'aes-256-cfb'),
           ('camellia-128-cfb', 'camellia-128-cfb'),
           ('camellia-192-cfb', 'camellia-192-cfb'),
           ('camellia-256-cfb', 'camellia-256-cfb'),
           ('chacha20-ietf', 'chacha20-ietf')]


class TrimmedCharField(forms.CharField):
    """Trim the contents of a CharField"""

    def clean(self, value):
        """Clean and validate the field value"""
        if value:
            value = value.strip()
Beispiel #41
0
service = None

managed_services = ['openvpn-server@freedombox']

managed_packages = ['openvpn', 'easy-rsa']

name = _('OpenVPN')

short_description = _('Virtual Private Network')

description = [
    format_lazy(
        _('Virtual Private Network (VPN) is a technique for securely '
          'connecting two devices in order to access resources of a '
          'private network.  While you are away from home, you can connect '
          'to your {box_name} in order to join your home network and '
          'access private/internal services provided by {box_name}. '
          'You can also access the rest of the Internet via {box_name} '
          'for added security and anonymity.'), box_name=_(cfg.box_name))
]


def init():
    """Initialize the OpenVPN module."""
    menu = main_menu.get('apps')
    menu.add_urlname(name, 'glyphicon-lock', 'openvpn:index',
                     short_description)

    global service
    setup_helper = globals()['setup_helper']
    if setup_helper.get_state() != 'needs-setup':
Beispiel #42
0
is_essential = True

depends = ['names']

managed_packages = ['certbot']

name = _('Let\'s Encrypt')

short_description = _('Certificates')

description = [
    format_lazy(
        _('A digital certificate allows users of a web service to verify the '
          'identity of the service and to securely communicate with it. '
          '{box_name} can automatically obtain and setup digital '
          'certificates for each available domain.  It does so by proving '
          'itself to be the owner of a domain to Let\'s Encrypt, a '
          'certificate authority (CA).'),
        box_name=_(cfg.box_name)),
    _('Let\'s Encrypt is a free, automated, and open certificate '
      'authority, run for the public\'s benefit by the Internet Security '
      'Research Group (ISRG).  Please read and agree with the '
      '<a href="https://letsencrypt.org/repository/">Let\'s Encrypt '
      'Subscriber Agreement</a> before using this service.')
]

service = None

MODULES_WITH_HOOKS = ['ejabberd']
LIVE_DIRECTORY = '/etc/letsencrypt/live/'
logger = logging.getLogger(__name__)
Beispiel #43
0
    """
    if not os.path.exists(domain_name_file):
        raise TahoeConfigurationError
    else:
        with open(domain_name_file) as dnf:
            return dnf.read().rstrip()


description = [
    _('Tahoe-LAFS is a decentralized secure file storage system. '
      'It uses provider independent security to store files over a '
      'distributed network of storage nodes. Even if some of the nodes fail, '
      'your files can be retrieved from the remaining nodes.'),
    format_lazy(
        _('This {box_name} hosts a storage node and an introducer by default. '
          'Additional introducers can be added, which will introduce this '
          'node to the other storage nodes.'),
        box_name=_(cfg.box_name)),
]


def init():
    """Intialize the module."""
    menu = main_menu.get('apps')
    menu.add_urlname(name, 'glyphicon-hdd', 'tahoe:index', short_description)

    global service
    setup_helper = globals()['setup_helper']
    if setup_helper.get_state() != 'needs-setup' and is_setup():
        service = service_module.Service(
            managed_services[0],
Beispiel #44
0
service = None

managed_services = ['infinoted']

managed_packages = ['infinoted']

name = _('infinoted')

short_description = _('Gobby Server')

description = [
    _('infinoted is a server for Gobby, a collaborative text editor.'),
    format_lazy(
        _('To use it, <a href="https://gobby.github.io/">download Gobby</a>, '
          'desktop client and install it. Then start Gobby and select '
          '"Connect to Server" and enter your {box_name}\'s domain name.'),
        box_name=_(cfg.box_name)),
]

clients = clients


def init():
    """Initialize the infinoted module."""
    menu = main_menu.get('apps')
    menu.add_urlname(name, 'glyphicon-pencil', 'infinoted:index',
                     short_description)

    global service
    setup_helper = globals()['setup_helper']
Beispiel #45
0
depends = ['apps']

service = None

managed_services = ['radicale']

managed_packages = ['radicale']

title = _('Calendar and Addressbook \n (Radicale)')

description = [
    format_lazy(
        _('Radicale is a CalDAV and CardDAV server. It allows synchronization '
          'and sharing of scheduling and contact data. To use Radicale, a '
          '<a href="http://radicale.org/user_documentation/'
          '#idcaldav-and-carddav-clients"> supported client application</a> '
          'is needed. Radicale can be accessed by any user with a {box_name} '
          'login.'), box_name=_(cfg.box_name)),
]

CONFIG_FILE = '/etc/radicale/config'


def init():
    """Initialize the radicale module."""
    menu = cfg.main_menu.get('apps:index')
    menu.add_urlname(title, 'glyphicon-calendar', 'radicale:index')

    global service
    setup_helper = globals()['setup_helper']
Beispiel #46
0
depends = ['apps']

service = None

managed_services = ['quasselcore']

managed_packages = ['quassel-core']

title = _('IRC Client (Quassel)')

description = [
    format_lazy(
        _('Quassel is an IRC application that is split into two parts, a '
          '"core" and a "client". This allows the core to remain connected '
          'to IRC servers, and to continue receiving messages, even when '
          'the client is disconnected. {box_name} can run the Quassel '
          'core service keeping you always online and one or more Quassel '
          'clients from a desktop or a mobile can be used to connect and '
          'disconnect from it.'), box_name=_(cfg.box_name)),

    _('You can connect to your Quassel core on the default Quassel port '
      '4242.  Clients to connect to Quassel from your '
      '<a href="http://quassel-irc.org/downloads">desktop</a> and '
      '<a href="http://quasseldroid.iskrembilen.com/">mobile</a> devices '
      'are available.')
]


def init():
    """Initialize the quassel module."""
    menu = cfg.main_menu.get('apps:index')
Beispiel #47
0
from plinth.signals import domain_added, domain_removed, domainname_change

version = 1

managed_services = ['cockpit.socket']

managed_packages = ['cockpit']

name = _('Cockpit')

short_description = _('Server Administration')

description = [
    format_lazy(
        _('Cockpit is a server manager that makes it easy to administer '
          'GNU/Linux servers via a web browser. On a {box_name}, controls '
          'are available for many advanced functions that are not usually '
          'required. A web based terminal for console operations is also '
          'available.'), box_name=_(cfg.box_name)),
    format_lazy(
        _('When enabled, Cockpit will be available from <a href="/_cockpit/">'
          '/_cockpit/</a> path on the web server. It can be accessed by '
          '<a href="/plinth/sys/users">any user</a> with a {box_name} login. '
          'Sensitive information and system altering abilities are limited to '
          'users belonging to admin group.'),
        box_name=_(cfg.box_name)),
    _('Currently only limited functionality is available.'),
]

service = None

Beispiel #48
0
managed_packages = ['tt-rss', 'postgresql', 'dbconfig-pgsql',
                    'php-pgsql', 'python3-psycopg2']

name = _('Tiny Tiny RSS')

short_description = _('News Feed Reader')

description = [
    _('Tiny Tiny RSS is a news feed (RSS/Atom) reader and aggregator, '
      'designed to allow reading news from any location, while feeling as '
      'close to a real desktop application as possible.'),

    format_lazy(
        _('When enabled, Tiny Tiny RSS will be available from <a href="/tt-'
          'rss">/tt-rss</a> path on the web server. It can be accessed by '
          'any <a href="/plinth/sys/users">user with a {box_name} login</a>.'),
        box_name=_(cfg.box_name)),

    format_lazy(
        _('When using a mobile or desktop application for Tiny Tiny RSS, use '
          'the URL <a href="/tt-rss-app/">/tt-rss-app</a> for connecting.'))
]

clients = clients

group = ('feed-reader', _('Read and subscribe to news feeds'))

service = None

Beispiel #49
0
"""
Plinth module for system section page
"""

from django.utils.translation import ugettext_lazy as _

from plinth import cfg
from plinth.utils import format_lazy


version = 1

is_essential = True

title = _('System Configuration')

description = [
    format_lazy(
        _('Here you can administrate the underlying system of your '
          '{box_name}.'), box_name=_(cfg.box_name)),

    format_lazy(
        _('The options affect the {box_name} at its most general level, '
          'so be careful!'), box_name=_(cfg.box_name))
]


def init():
    """Initialize the system module"""
    cfg.main_menu.add_urlname(title, 'glyphicon-cog', 'system:index')
Beispiel #50
0
from django.utils.translation import ugettext_lazy as _

from plinth import cfg
from plinth.utils import format_lazy

version = 1

depends = ['apps']

title = _('Dynamic DNS Client')

description = [
    format_lazy(
        _('If your Internet provider changes your IP address periodically '
          '(i.e. every 24h), it may be hard for others to find you on the '
          'Internet. This will prevent others from finding services which are '
          'provided by this {box_name}.'),
        box_name=_(cfg.box_name)),

    _('The solution is to assign a DNS name to your IP address and '
      'update the DNS name every time your IP is changed by your '
      'Internet provider. Dynamic DNS allows you to push your current '
      'public IP address to a '
      '<a href=\'http://gnudip2.sourceforge.net/\' target=\'_blank\'> '
      'GnuDIP</a> server. Afterwards, the server will assign your DNS name '
      'to the new IP, and if someone from the Internet asks for your DNS '
      'name, they will get a response with your current IP address.')
]


def init():
Beispiel #51
0
managed_services = ['privoxy']

managed_packages = ['privoxy']

title = _('Web Proxy \n (Privoxy)')

description = [
    _('Privoxy is a non-caching web proxy with advanced filtering '
      'capabilities for enhancing privacy, modifying web page data and '
      'HTTP headers, controlling access, and removing ads and other '
      'obnoxious Internet junk. '),

    format_lazy(
        _('You can use Privoxy by modifying your browser proxy settings to '
          'your {box_name} hostname (or IP address) with port 8118. '
          'While using Privoxy, you can see its configuration details and '
          'documentation at '
          '<a href="http://config.privoxy.org">http://config.privoxy.org/</a> '
          'or <a href="http://p.p">http://p.p</a>.'),
        box_name=_(cfg.box_name)),
]

service = None


def init():
    """Intialize the module."""
    menu = cfg.main_menu.get('apps:index')
    menu.add_urlname(title, 'glyphicon-cloud-upload', 'privoxy:index')

    global service
    setup_helper = globals()['setup_helper']
Beispiel #52
0
from plinth.utils import format_lazy

version = 1

is_essential = True

depends = ['system']

managed_packages = ['firewalld']

title = _('Firewall')

description = [
    format_lazy(
        _('Firewall is a security system that controls the incoming and '
          'outgoing network traffic on your {box_name}. Keeping a '
          'firewall enabled and properly configured reduces risk of '
          'security threat from the Internet.'), box_name=cfg.box_name)
]

LOGGER = logging.getLogger(__name__)


def init():
    """Initailze firewall module"""
    menu = cfg.main_menu.get('system:index')
    menu.add_urlname(title, 'glyphicon-fire', 'firewall:index')

    service_enabled.connect(on_service_enabled)

Beispiel #53
0
is_essential = True

depends = ['names']

managed_packages = ['certbot']

name = _('Let\'s Encrypt')

short_description = _('Certificates')

description = [
    format_lazy(
        _('A digital certificate allows users of a web service to verify the '
          'identity of the service and to securely communicate with it. '
          '{box_name} can automatically obtain and setup digital '
          'certificates for each available domain.  It does so by proving '
          'itself to be the owner of a domain to Let\'s Encrypt, a '
          'certificate authority (CA).'), box_name=_(cfg.box_name)),

    _('Let\'s Encrypt is a free, automated, and open certificate '
      'authority, run for the public\'s benefit by the Internet Security '
      'Research Group (ISRG).  Please read and agree with the '
      '<a href="https://letsencrypt.org/repository/">Let\'s Encrypt '
      'Subscriber Agreement</a> before using this service.')
]


service = None

MODULES_WITH_HOOKS = ['ejabberd']
Beispiel #54
0
service = None

name = _('ikiwiki')

short_description = _('Wiki and Blog')

description = [
    _('ikiwiki is a simple wiki and blog application. It supports '
      'several lightweight markup languages, including Markdown, and '
      'common blogging functionality such as comments and RSS feeds. '
      'When enabled, the blogs and wikis will be available '
      'at <a href="/ikiwiki">/ikiwiki</a> (once created).'),

    format_lazy(
        _('Only {box_name} users in the <b>admin</b> group can <i>create</i> '
          'and <i>manage</i> blogs and wikis, but any user in the <b>wiki</b> '
          'group can <i>edit</i> existing ones. In the <a href="/plinth/sys/'
          'users">User Configuration</a> you can change these '
          'permissions or add new users.'), box_name=_(cfg.box_name))
]

clients = clients


group = ('wiki', _('View and edit wiki applications'))


def init():
    """Initialize the ikiwiki module."""
    menu = main_menu.get('apps')
    menu.add_urlname(name, 'glyphicon-edit', 'ikiwiki:index', short_description)
Beispiel #55
0
managed_packages = ['matrix-synapse', 'matrix-synapse-ldap3']

managed_paths = [pathlib.Path('/etc/matrix-synapse/')]

_description = [
    _('<a href="https://matrix.org/docs/guides/faq.html">Matrix</a> is an new '
      'ecosystem for open, federated instant messaging and VoIP. Synapse is a '
      'server implementing the Matrix protocol. It provides chat groups, '
      'audio/video calls, end-to-end encryption, multiple device '
      'synchronization and does not require phone numbers to work. Users on a '
      'given Matrix server can converse with users on all other Matrix '
      'servers via federation.'),
    format_lazy(_(
        'Matrix Synapse needs a STUN/TURN server for audio/video calls. '
        'Install the <a href={coturn_url}>Coturn</a> app or configure '
        'an external server.'),
                coturn_url=reverse_lazy('coturn:index'))
]

depends = ['coturn']

logger = logging.getLogger(__name__)

CONF_DIR = "/etc/matrix-synapse/conf.d/"

ORIG_CONF_PATH = '/etc/matrix-synapse/homeserver.yaml'
SERVER_NAME_PATH = CONF_DIR + 'server_name.yaml'
STATIC_CONF_PATH = CONF_DIR + 'freedombox-static.yaml'
LISTENERS_CONF_PATH = CONF_DIR + 'freedombox-listeners.yaml'
REGISTRATION_CONF_PATH = CONF_DIR + 'freedombox-registration.yaml'
Beispiel #56
0
from django.utils.translation import ugettext_lazy as _
from plinth import cfg
from plinth.utils import format_lazy

from . import utils

version = 1

depends = ['apps', 'names']

title = _('Public Visibility (PageKite)')

description = [
    format_lazy(
        _('PageKite is a system for exposing {box_name} services when '
          'you don\'t have a direct connection to the Internet. You only '
          'need this if your {box_name} services are unreachable from '
          'the rest of the Internet. This includes the following '
          'situations:'), box_name=_(cfg.box_name)),

    format_lazy(
        _('{box_name} is behind a restricted firewall.'),
        box_name=_(cfg.box_name)),

    format_lazy(
        _('{box_name} is connected to a (wireless) router which you '
          'don\'t control.'), box_name=_(cfg.box_name)),

    _('Your ISP does not provide you an external IP address and '
      'instead provides Internet connection through NAT.'),

    _('Your ISP does not provide you a static IP address and your IP '
Beispiel #57
0
managed_services = ['syncthing']

managed_packages = ['syncthing']

title = _('File Synchronization \n (Syncthing)')

description = [
    _('Syncthing is an application to synchronize files across multiple '
      'devices, e.g. your desktop computer and mobile phone.  Creation, '
      'modification, or deletion of files on one device will be automatically '
      'replicated on all other devices that also run Syncthing.'),
    format_lazy(_(
        'Running Syncthing on {box_name} provides an extra synchronization '
        'point for your data that is available most of the time, allowing '
        'your devices to synchronize more often.  {box_name} runs a single '
        'instance of Syncthing that may be used by multiple users.  Each '
        'user\'s set of devices may be synchronized with a distinct set of '
        'folders.  The web interface on {box_name} is only available for '
        'users belonging to the "admin" group.'),
                box_name=_(cfg.box_name)),
    _('When enabled, Syncthing\'s web interface will be available from '
      '<a href="/syncthing/">/syncthing</a>.  Desktop and mobile clients are '
      'also <a href="https://syncthing.net/">available</a>.'),
]

service = None


def init():
    """Intialize the module."""
    menu = main_menu.get('apps')
Beispiel #58
0
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#

from django.utils.translation import ugettext_lazy as _

from plinth import cfg
from plinth.clients import validate
from plinth.utils import format_lazy

clients = validate([{
    'name':
        _('Gobby'),
    'description':
        _('Gobby is a collaborative text editor'),
    'usage':
        format_lazy(
            _('Start Gobby and select "Connect to Server" and '
              'enter your {box_name}\'s domain name.'),
            box_name=_(cfg.box_name)),
    'platforms': [{
        'type': 'download',
        'os': 'windows',
        'url': 'https://github.com/gobby/gobby/wiki/Download'
    }, {
        'type': 'package',
        'format': 'deb',
        'name': 'gobby'
    }]
}])