示例#1
0
def create_link(modeladmin, request, queryset):
    account_id = None
    for user in queryset:
        account_id = account_id or user.account_id
        if user.account_id != account_id:
            messages.error(request,
                           "Users from the same account should be selected.")
            return
    user = queryset[0]
    form = LinkForm(user, queryset=queryset)
    action_value = 'create_link'
    if request.POST.get('post') == 'generic_confirmation':
        form = LinkForm(user, request.POST, queryset=queryset)
        if form.is_valid():
            cleaned_data = form.cleaned_data
            operations = []
            for user in queryset:
                base_home = cleaned_data['base_home']
                extension = cleaned_data['home_extension']
                target = os.path.join(base_home, extension)
                default_name = os.path.join(user.home,
                                            os.path.basename(target))
                link_name = cleaned_data['link_name'] or default_name
                user.create_link_target = target
                user.create_link_name = link_name
                operations.extend(
                    Operation.create_for_action(user, 'create_link'))
                context = {
                    'target': target,
                    'link_name': link_name,
                }
                msg = _(
                    "Created link from %(target)s to %(link_name)s") % context
                modeladmin.log_change(request, request.user, msg)
            logs = Operation.execute(operations)
            if logs:
                helpers.message_user(request, logs)
            else:
                messages.error(request,
                               "No backend operation has been executed.")
            return
    opts = modeladmin.model._meta
    app_label = opts.app_label
    context = {
        'title': _("Create link"),
        'action_name': _("Create link"),
        'action_value': action_value,
        'queryset': queryset,
        'opts': opts,
        'obj': user,
        'app_label': app_label,
        'action_checkbox_name': admin.helpers.ACTION_CHECKBOX_NAME,
        'form': form,
    }
    return TemplateResponse(request,
                            'admin/systemusers/systemuser/create_link.html',
                            context)
示例#2
0
def set_permission(modeladmin, request, queryset):
    account_id = None
    for user in queryset:
        account_id = account_id or user.account_id
        if user.account_id != account_id:
            messages.error(request, "Users from the same account should be selected.")
            return
    user = queryset[0]
    form = PermissionForm(user)
    action_value = 'set_permission'
    if request.POST.get('post') == 'generic_confirmation':
        form = PermissionForm(user, request.POST)
        if form.is_valid():
            cleaned_data = form.cleaned_data
            operations = []
            for user in queryset:
                base_home = cleaned_data['base_home']
                extension = cleaned_data['home_extension']
                action = cleaned_data['set_action']
                perms = cleaned_data['permissions']
                user.set_perm_action = action
                user.set_perm_base_home = base_home
                user.set_perm_home_extension = extension
                user.set_perm_perms = perms
                operations.extend(Operation.create_for_action(user, 'set_permission'))
                verbose_action = get_verbose_choice(form.fields['set_action'].choices,
                    user.set_perm_action)
                verbose_permissions = get_verbose_choice(form.fields['permissions'].choices,
                    user.set_perm_perms)
                context = {
                    'action': verbose_action,
                    'perms': verbose_permissions.lower(),
                    'to': os.path.join(user.set_perm_base_home, user.set_perm_home_extension),
                }
                msg = _("%(action)s %(perms)s permission to %(to)s") % context
                modeladmin.log_change(request, user, msg)
            if not operations:
                messages.error(request, _("No backend operation has been executed."))
            else:
                logs = Operation.execute(operations)
                helpers.message_user(request, logs)
            return
    opts = modeladmin.model._meta
    app_label = opts.app_label
    context = {
        'title': _("Set permission"),
        'action_name': _("Set permission"),
        'action_value': action_value,
        'queryset': queryset,
        'opts': opts,
        'obj': user,
        'app_label': app_label,
        'action_checkbox_name': admin.helpers.ACTION_CHECKBOX_NAME,
        'form': form,
    }
    return TemplateResponse(request, 'admin/systemusers/systemuser/set_permission.html', context)
示例#3
0
def create_link(modeladmin, request, queryset):
    account_id = None
    for user in queryset:
        account_id = account_id or user.account_id
        if user.account_id != account_id:
            messages.error(request, "Users from the same account should be selected.")
            return
    user = queryset[0]
    form = LinkForm(user, queryset=queryset)
    action_value = 'create_link'
    if request.POST.get('post') == 'generic_confirmation':
        form = LinkForm(user, request.POST, queryset=queryset)
        if form.is_valid():
            cleaned_data = form.cleaned_data
            operations = []
            for user in queryset:
                base_home = cleaned_data['base_home']
                extension = cleaned_data['home_extension']
                target = os.path.join(base_home, extension)
                default_name = os.path.join(user.home, os.path.basename(target))
                link_name = cleaned_data['link_name'] or default_name
                user.create_link_target = target
                user.create_link_name = link_name
                operations.extend(Operation.create_for_action(user, 'create_link'))
                context = {
                    'target': target,
                    'link_name': link_name,
                }
                msg = _("Created link from %(target)s to %(link_name)s") % context
                modeladmin.log_change(request, request.user, msg)
            logs = Operation.execute(operations)
            if logs:
                helpers.message_user(request, logs)
            else:
                messages.error(request, "No backend operation has been executed.")
            return
    opts = modeladmin.model._meta
    app_label = opts.app_label
    context = {
        'title': _("Create link"),
        'action_name': _("Create link"),
        'action_value': action_value,
        'queryset': queryset,
        'opts': opts,
        'obj': user,
        'app_label': app_label,
        'action_checkbox_name': admin.helpers.ACTION_CHECKBOX_NAME,
        'form': form,
    }
    return TemplateResponse(request, 'admin/systemusers/systemuser/create_link.html', context)
示例#4
0
def retry_backend(modeladmin, request, queryset):
    related_operations = queryset.values_list('operations__id', flat=True).distinct()
    related_operations = BackendOperation.objects.filter(pk__in=related_operations)
    related_operations = related_operations.select_related('log__server').prefetch_related('instance')
    if request.POST.get('post') == 'generic_confirmation':
        operations = []
        for operation in related_operations:
            if operation.instance:
                op = Operation.load(operation)
                operations.append(op)
        if not operations:
            messages.warning(request, _("No backend operation has been executed."))
        else:
            logs = Operation.execute(operations)
            message_user(request, logs)
        for backendlog in queryset:
            modeladmin.log_change(request, backendlog, 'Retried')
        return
    opts = modeladmin.model._meta
    display_objects = []
    deleted_objects = []
    for op in related_operations:
        if not op.instance:
            deleted_objects.append(op)
        else:
            context = {
                'backend': op.log.backend,
                'action': op.action,
                'instance': op.instance,
                'instance_url': change_url(op.instance),
                'server': op.log.server,
                'server_url': change_url(op.log.server),
            }
            display_objects.append(mark_safe(
                '%(backend)s.%(action)s(<a href="%(instance_url)s">%(instance)s</a>) @ <a href="%(server_url)s">%(server)s</a>' % context
            ))
    context = {
        'title': _("Are you sure to execute the following backends?"),
        'action_name': _('Retry backend'),
        'action_value': 'retry_backend',
        'display_objects': display_objects,
        'deleted_objects': deleted_objects,
        'queryset': queryset,
        'opts': opts,
        'app_label': opts.app_label,
        'action_checkbox_name': helpers.ACTION_CHECKBOX_NAME,
        'obj': get_object_from_url(modeladmin, request),
    }
    return render(request, 'admin/orchestration/backends/retry.html', context)
示例#5
0
def letsencrypt(modeladmin, request, queryset):
    wildcards = set()
    domains = set()
    content_error = ''
    contentless = queryset.exclude(content__path='/').distinct()
    if contentless:
        content_error = ungettext(
            ugettext(
                "Selected website %s doesn't have a webapp mounted on <tt>/</tt>."
            ),
            ugettext(
                "Selected websites %s don't have a webapp mounted on <tt>/</tt>."
            ),
            len(contentless),
        )
        content_error += ugettext(
            "<br>Websites need a webapp (e.g. static) mounted on </tt>/</tt> "
            "for let's encrypt HTTP-01 challenge to work.")
        content_error = content_error % ', '.join(
            (admin_link()(website) for website in contentless))
        content_error = '<ul class="errorlist"><li>%s</li></ul>' % content_error
    queryset = queryset.prefetch_related('domains')
    for website in queryset:
        for domain in website.domains.all():
            if domain.name.startswith('*.'):
                wildcards.add(domain.name)
            else:
                domains.add(domain.name)
    form = LetsEncryptForm(domains,
                           wildcards,
                           initial={'domains': '\n'.join(domains)})
    action_value = 'letsencrypt'
    if request.POST.get('post') == 'generic_confirmation':
        form = LetsEncryptForm(domains, wildcards, request.POST)
        if not content_error and form.is_valid():
            cleaned_data = form.cleaned_data
            domains = set(cleaned_data['domains'])
            operations = []
            for website in queryset:
                website_domains = [d.name for d in website.domains.all()]
                encrypt_domains = set()
                for domain in domains:
                    if is_valid_domain(domain, website_domains, wildcards):
                        encrypt_domains.add(domain)
                website.encrypt_domains = encrypt_domains
                operations.extend(
                    Operation.create_for_action(website, 'encrypt'))
                modeladmin.log_change(request, website, _("Encrypted!"))
            if not operations:
                messages.error(request,
                               _("No backend operation has been executed."))
            else:
                logs = Operation.execute(operations)
                helpers.message_user(request, logs)
                live_lineages = read_live_lineages(logs)
                errors = 0
                successes = 0
                no_https = 0
                for website in queryset:
                    try:
                        configure_cert(website, live_lineages)
                    except LookupError:
                        errors += 1
                        messages.error(
                            request,
                            _("No lineage found for website %s") %
                            website.name)
                    else:
                        if website.protocol == website.HTTP:
                            no_https += 1
                        website.save(update_fields=('name', ))
                    successes += 1
                context = {
                    'name': website.name,
                    'errors': errors,
                    'successes': successes,
                    'no_https': no_https
                }
                if errors:
                    msg = ungettext(
                        _("No lineages found for websites {name}."),
                        _("No lineages found for {errors} websites."), errors)
                    messages.error(request, msg % context)
                if successes:
                    msg = ungettext(
                        _("{name} website has successfully been encrypted."),
                        _("{successes} websites have been successfully encrypted."
                          ), successes)
                    messages.success(request, msg.format(**context))
                if no_https:
                    msg = ungettext(
                        _("{name} website does not have <b>HTTPS protocol</b> enabled."
                          ),
                        _("{no_https} websites do not have <b>HTTPS protocol</b> enabled."
                          ), no_https)
                    messages.warning(request, mark_safe(msg.format(**context)))
                return
    opts = modeladmin.model._meta
    app_label = opts.app_label
    context = {
        'title':
        _("Let's encrypt!"),
        'action_name':
        _("Encrypt"),
        'content_message':
        ugettext(
            "You are going to request certificates for the following domains.<br>"
            "This operation is safe to run multiple times, "
            "existing certificates will not be regenerated. "
            "Also notice that let's encrypt does not currently support wildcard certificates."
        ) + content_error,
        'action_value':
        action_value,
        'queryset':
        queryset,
        'opts':
        opts,
        'obj':
        website if len(queryset) == 1 else None,
        'app_label':
        app_label,
        'action_checkbox_name':
        admin.helpers.ACTION_CHECKBOX_NAME,
        'form':
        form,
    }
    return TemplateResponse(request,
                            'admin/orchestra/generic_confirmation.html',
                            context)
示例#6
0
def letsencrypt(modeladmin, request, queryset):
    wildcards = set()
    domains = set()
    content_error = ''
    contentless = queryset.exclude(content__path='/').distinct()
    if contentless:
        content_error = ungettext(
            ugettext("Selected website %s doesn't have a webapp mounted on <tt>/</tt>."),
            ugettext("Selected websites %s don't have a webapp mounted on <tt>/</tt>."),
            len(contentless),
        )
        content_error += ugettext("<br>Websites need a webapp (e.g. static) mounted on </tt>/</tt> "
                                  "for let's encrypt HTTP-01 challenge to work.")
        content_error = content_error % ', '.join((admin_link()(website) for website in contentless))
        content_error = '<ul class="errorlist"><li>%s</li></ul>' % content_error
    queryset = queryset.prefetch_related('domains')
    for website in queryset:
        for domain in website.domains.all():
            if domain.name.startswith('*.'):
                wildcards.add(domain.name)
            else:
                domains.add(domain.name)
    form = LetsEncryptForm(domains, wildcards, initial={'domains': '\n'.join(domains)})
    action_value = 'letsencrypt'
    if request.POST.get('post') == 'generic_confirmation':
        form = LetsEncryptForm(domains, wildcards, request.POST)
        if not content_error and form.is_valid():
            cleaned_data = form.cleaned_data
            domains = set(cleaned_data['domains'])
            operations = []
            for website in queryset:
                website_domains = [d.name for d in website.domains.all()]
                encrypt_domains = set()
                for domain in domains:
                    if is_valid_domain(domain, website_domains, wildcards):
                        encrypt_domains.add(domain)
                website.encrypt_domains = encrypt_domains
                operations.extend(Operation.create_for_action(website, 'encrypt'))
                modeladmin.log_change(request, website, _("Encrypted!"))
            if not operations:
                messages.error(request, _("No backend operation has been executed."))
            else:
                logs = Operation.execute(operations)
                helpers.message_user(request, logs)
                live_lineages = read_live_lineages(logs)
                errors = 0
                successes = 0
                no_https = 0
                for website in queryset:
                    try:
                        configure_cert(website, live_lineages)
                    except LookupError:
                        errors += 1
                        messages.error(request, _("No lineage found for website %s") % website.name)
                    else:
                        if website.protocol == website.HTTP:
                            no_https += 1
                        website.save(update_fields=('name',))
                    successes += 1
                context = {
                    'name': website.name,
                    'errors': errors,
                    'successes': successes,
                    'no_https': no_https
                }
                if errors:
                    msg = ungettext(
                        _("No lineages found for websites {name}."),
                        _("No lineages found for {errors} websites."),
                        errors)
                    messages.error(request, msg % context)
                if successes:
                    msg = ungettext(
                        _("{name} website has successfully been encrypted."),
                        _("{successes} websites have been successfully encrypted."),
                        successes)
                    messages.success(request, msg.format(**context))
                if no_https:
                    msg = ungettext(
                        _("{name} website does not have <b>HTTPS protocol</b> enabled."),
                        _("{no_https} websites do not have <b>HTTPS protocol</b> enabled."),
                        no_https)
                    messages.warning(request, mark_safe(msg.format(**context)))
                return
    opts = modeladmin.model._meta
    app_label = opts.app_label
    context = {
        'title': _("Let's encrypt!"),
        'action_name': _("Encrypt"),
        'content_message': ugettext("You are going to request certificates for the following domains.<br>"
            "This operation is safe to run multiple times, "
            "existing certificates will not be regenerated. "
            "Also notice that let's encrypt does not currently support wildcard certificates.") + content_error,
        'action_value': action_value,
        'queryset': queryset,
        'opts': opts,
        'obj': website if len(queryset) == 1 else None,
        'app_label': app_label,
        'action_checkbox_name': admin.helpers.ACTION_CHECKBOX_NAME,
        'form': form,
    }
    return TemplateResponse(request, 'admin/orchestra/generic_confirmation.html', context)
示例#7
0
def set_permission(modeladmin, request, queryset):
    account_id = None
    for user in queryset:
        account_id = account_id or user.account_id
        if user.account_id != account_id:
            messages.error(request,
                           "Users from the same account should be selected.")
            return
    user = queryset[0]
    form = PermissionForm(user)
    action_value = 'set_permission'
    if request.POST.get('post') == 'generic_confirmation':
        form = PermissionForm(user, request.POST)
        if form.is_valid():
            cleaned_data = form.cleaned_data
            operations = []
            for user in queryset:
                base_home = cleaned_data['base_home']
                extension = cleaned_data['home_extension']
                action = cleaned_data['set_action']
                perms = cleaned_data['permissions']
                user.set_perm_action = action
                user.set_perm_base_home = base_home
                user.set_perm_home_extension = extension
                user.set_perm_perms = perms
                operations.extend(
                    Operation.create_for_action(user, 'set_permission'))
                verbose_action = get_verbose_choice(
                    form.fields['set_action'].choices, user.set_perm_action)
                verbose_permissions = get_verbose_choice(
                    form.fields['permissions'].choices, user.set_perm_perms)
                context = {
                    'action':
                    verbose_action,
                    'perms':
                    verbose_permissions.lower(),
                    'to':
                    os.path.join(user.set_perm_base_home,
                                 user.set_perm_home_extension),
                }
                msg = _("%(action)s %(perms)s permission to %(to)s") % context
                modeladmin.log_change(request, user, msg)
            if not operations:
                messages.error(request,
                               _("No backend operation has been executed."))
            else:
                logs = Operation.execute(operations)
                helpers.message_user(request, logs)
            return
    opts = modeladmin.model._meta
    app_label = opts.app_label
    context = {
        'title': _("Set permission"),
        'action_name': _("Set permission"),
        'action_value': action_value,
        'queryset': queryset,
        'opts': opts,
        'obj': user,
        'app_label': app_label,
        'action_checkbox_name': admin.helpers.ACTION_CHECKBOX_NAME,
        'form': form,
    }
    return TemplateResponse(
        request, 'admin/systemusers/systemuser/set_permission.html', context)
示例#8
0
def orchestrate(modeladmin, request, queryset):
    operations = set()
    action = Operation.SAVE
    operations = OrderedSet()
    if queryset.model is Route:
        for route in queryset:
            routes = [route]
            backend = route.backend_class
            if action not in backend.actions:
                continue
            for instance in backend.model_class().objects.all():
                if route.matches(instance):
                    operations.add(Operation(backend, instance, action, routes=routes))
    elif queryset.model is Server:
        models = set()
        for server in queryset:
            routes = server.routes.all()
            for route in routes.filter(is_active=True):
                model = route.backend_class.model_class()
                models.add(model)
        querysets = [model.objects.order_by('id') for model in models]
        
        route_cache = {}
        for model in models:
            for instance in model.objects.all():
                manager.collect(instance, action, operations=operations, route_cache=route_cache)
            routes = []
        result = []
        for operation in operations:
            routes = [route for route in operation.routes if route.host in queryset]
            operation.routes = routes
            if routes:
                result.append(operation)
        operations = result
    if not operations:
        messages.warning(request, _("No related operations."))
        return
    
    if request.POST.get('post') == 'generic_confirmation':
        logs = Operation.execute(operations)
        message_user(request, logs)
        for obj in queryset:
            modeladmin.log_change(request, obj, 'Orchestrated')
        return
    
    opts = modeladmin.model._meta
    display_objects = {}
    for operation in operations:
        try:
            display_objects[operation.backend].append(operation)
        except KeyError:
            display_objects[operation.backend] = [operation]
    context = {
        'title': _("Are you sure to execute the following operations?"),
        'action_name': _('Orchestrate'),
        'action_value': 'orchestrate',
        'display_objects': display_objects,
        'queryset': queryset,
        'opts': opts,
        'app_label': opts.app_label,
        'action_checkbox_name': helpers.ACTION_CHECKBOX_NAME,
        'obj': get_object_from_url(modeladmin, request),
    }
    return render(request, 'admin/orchestration/orchestrate.html', context)