示例#1
0
class IssueKeyForm(BaseForm):

    label = _(u'Issue Service Key')
    description = _(u'Issue a key to be used for authentication '
                    u'by a service application')

    fields = Fields(IKeyMetadataSchema).select('title', 'ip_range')

    download_key_template = ViewPageTemplateFile('download_key.pt')

    @button.buttonAndHandler(_(u'Issue key'), name='save')
    def handleApply(self, action):
        data, errors = self.extractData()
        if errors:
            self.status = self.formErrorsMessage
            return

        user_id = api.user.get_current().id

        private_key, service_key = self.get_plugin().issue_keypair(
            user_id, data['title'], data['ip_range'])

        self._key_issued = True
        self._generated_private_key = private_key
        self._generated_service_key = service_key

        msg = _('Key created: ${key_id}',
                mapping={'key_id': service_key['key_id']})
        api.portal.show_message(msg, getRequest())

    @button.buttonAndHandler(_(u'Cancel'), name='cancel')
    def handleCancel(self, action):
        api.portal.show_message(_(u'Key creation cancelled.'), getRequest())
        return self.request.RESPONSE.redirect(self.main_url)

    def render(self):
        if getattr(self, '_key_issued', False) is True:
            # We carry over the newly issued key in these attributes on the
            # view to offer the private key for download exactly once.
            private_key = self._generated_private_key
            service_key = self._generated_service_key

            del self._generated_private_key

            json_keyfile = create_json_keyfile(private_key, service_key)
            template_vars = {
                'key_id': service_key['key_id'],
                'title': service_key['title'],
                'json_keyfile': json_keyfile,
            }
            return self.download_key_template(**template_vars)

        return super(IssueKeyForm, self).render()
    def revoke_selected_keys(self):
        user_id = api.user.get_current().id
        selected_keys = self.request.form.get('selected_keys', [])

        storage = CredentialStorage(self.plugin)
        for key_id in selected_keys:
            storage.revoke_service_key(user_id, key_id)

        api.portal.show_message(_('Keys revoked.'), getRequest())
        return self.request.RESPONSE.redirect(self.main_url)
示例#3
0
def valid_ip_range(value):
    """Form validator that checks for a valid IP range specification.
    """
    try:
        parse_ip_range(value)
    except InvalidIPRangeSpecification as exc:
        raise Invalid(
            _('Invalid IP range: ${ip_range_error}',
              mapping={'ip_range_error': str(exc)}))
    return True
示例#4
0
class IKeyMetadataSchema(model.Schema):
    """
    """

    title = schema.TextLine(title=_(u'label_title', default=u'Title'), )

    key_id = schema.TextLine(
        title=_(u'label_key_id', default=u'Key ID'),
        readonly=True,
    )

    user_id = schema.TextLine(
        title=_(u'label_user_id', default=u'User ID'),
        readonly=True,
    )

    issued = schema.Datetime(
        title=_(u'label_issued', default=u'Issued'),
        readonly=True,
    )

    ip_range = schema.TextLine(
        title=_(u'label_ip_range', default=u'IP Range'),
        required=False,
        constraint=valid_ip_range,
        description=
        _(u'Allowed IP range specification in '
          u'<strong><a href="https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing#CIDR_notation">'  # noqa
          u'CIDR notation</a></strong>. '
          u'Multiple comma-separated addresses / networks may be supplied.'),
    )
示例#5
0
    def handleApply(self, action):
        data, errors = self.extractData()
        if errors:
            self.status = self.formErrorsMessage
            return

        user_id = api.user.get_current().id

        private_key, service_key = self.get_plugin().issue_keypair(
            user_id, data['title'], data['ip_range'])

        self._key_issued = True
        self._generated_private_key = private_key
        self._generated_service_key = service_key

        msg = _('Key created: ${key_id}',
                mapping={'key_id': service_key['key_id']})
        api.portal.show_message(msg, getRequest())
示例#6
0
 def handleCancel(self, action):
     api.portal.show_message(_('Edit cancelled'), getRequest())
     return self.request.RESPONSE.redirect(self.main_url)
示例#7
0
class EditKeyForm(BaseForm):

    label = _(u'Edit Service Key')

    successMessage = Z3CFormMF('Data successfully updated.')
    noChangesMessage = Z3CFormMF('No changes were applied.')

    fields = Fields(IKeyMetadataSchema)

    def updateWidgets(self, *args, **kwargs):
        super(EditKeyForm, self).updateWidgets(*args, **kwargs)

        saving = 'form.buttons.save' in self.request

        # Prefill form widgets with persisted values from DB
        key = self.get_key()
        for widget in self.widgets.values():
            # Always prefill readonly widgets.
            #
            # Prefill other widgets only upon initial rendering of the form,
            # not when trying to save - this is so we don't override
            # actual user provided inputs with persisted values from the
            # DB when rendering the form in the case of validation errors.
            if widget.field.readonly or not saving:
                name = widget.field.getName()
                value = key[name]
                converter = IDataConverter(widget)
                widget.value = converter.toWidgetValue(value)

    def get_key(self):
        key_id = self.request.form['key_id']
        storage = CredentialStorage(self.get_plugin())
        key = storage.get_service_key(key_id)
        return key

    def action(self):
        """Redefine <form action=''> attribute.
        """
        return self.request.getURL() + '?key_id=%s' % self.request['key_id']

    def field_value_has_changed(self, field, new_value, key):
        name = field.getName()
        old_value = key[name]
        return old_value != new_value

    def applyChanges(self, data):
        # Based on z3c.form.form.applyChanges, but without firing events
        key = self.get_key()

        changes = {}
        for name, field in self.fields.items():
            # If the field is not in the data, then go on to the next one
            try:
                new_value = data[name]
            except KeyError:
                continue
            # If the value is NOT_CHANGED, ignore it, since the
            # widget/converter sent a strong message not to do so.
            if new_value is NOT_CHANGED:
                continue
            if self.field_value_has_changed(field.field, new_value, key):
                # Only update the data if it changed
                # TODO: Should we possibly be using toFieldValue here?
                key[name] = new_value

                # Record the change using information required later
                changes.setdefault(field.interface, []).append(name)

        return changes

    @button.buttonAndHandler(_(u'Save'), name='save')
    def handleApply(self, action):
        data, errors = self.extractData()
        if errors:
            self.status = self.formErrorsMessage
            return
        changes = self.applyChanges(data)
        if changes:
            api.portal.show_message(self.successMessage, getRequest())
        else:
            api.portal.show_message(self.noChangesMessage, getRequest())
        return self.request.RESPONSE.redirect(self.main_url)

    @button.buttonAndHandler(_(u'Cancel'), name='cancel')
    def handleCancel(self, action):
        api.portal.show_message(_('Edit cancelled'), getRequest())
        return self.request.RESPONSE.redirect(self.main_url)