Beispiel #1
0
class EditOrganizationMemberForm(forms.ModelForm):
    type = CustomTypedChoiceField(label=_('Membership Type'),
                                  choices=(),
                                  coerce=int)
    has_global_access = forms.BooleanField(
        label=
        _('This member should have access to all teams within the organization.'
          ),
        required=False,
    )
    teams = forms.ModelMultipleChoiceField(
        queryset=Team.objects.none(),
        widget=forms.CheckboxSelectMultiple(),
        required=False,
    )

    class Meta:
        fields = ('type', 'has_global_access')
        model = OrganizationMember

    def __init__(self, authorizing_access, *args, **kwargs):
        super(EditOrganizationMemberForm, self).__init__(*args, **kwargs)

        self.fields['type'].choices = [
            m for m in MEMBERSHIP_CHOICES if m[0] >= authorizing_access
        ]
        self.fields['teams'].queryset = Team.objects.filter(
            organization=self.instance.organization, )

    def save(self, actor, organization, ip_address=None):
        om = super(EditOrganizationMemberForm, self).save()

        for team in self.cleaned_data['teams']:
            OrganizationMemberTeam.objects.create_or_update(
                team=team,
                organizationmember=om,
            )

        OrganizationMemberTeam.objects.filter(
            organizationmember=om,
            is_active=True,
        ).exclude(team__in=self.cleaned_data['teams']).delete()

        AuditLogEntry.objects.create(
            organization=organization,
            actor=actor,
            ip_address=ip_address,
            target_object=om.id,
            target_user=om.user,
            event=AuditLogEntryEvent.MEMBER_EDIT,
            data=om.get_audit_log_data(),
        )

        return om
Beispiel #2
0
class EditProjectForm(forms.ModelForm):
    name = forms.CharField(
        label=_('Project Name'),
        max_length=200,
        widget=forms.TextInput(attrs={'placeholder': _('Production')}))
    platform = forms.ChoiceField(
        choices=Project._meta.get_field('platform').get_choices(
            blank_choice=BLANK_CHOICE),
        widget=forms.Select(
            attrs={'data-placeholder': _('Select a platform')}))
    public = forms.BooleanField(
        required=False,
        help_text=_('Imply public access to any event for this project.'))
    team = CustomTypedChoiceField(choices=(), coerce=int, required=False)
    origins = OriginsField(
        label=_('Allowed Domains'),
        required=False,
        help_text=_('Separate multiple entries with a newline.'))
    token = forms.CharField(
        label=_('Security token'),
        required=True,
        help_text=
        _('Outbound requests matching Allowed Domains will have the header "X-Sentry-Token: {token}" appended.'
          ))
    resolve_age = RangeField(help_text=_(
        'Treat an event as resolved if it hasn\'t been seen for this amount of time.'
    ),
                             required=False,
                             min_value=0,
                             max_value=168,
                             step_value=1)
    scrub_data = forms.BooleanField(
        label=_('Data Scrubber'),
        help_text=
        _('Apply server-side data scrubbing to prevent things like passwords and credit cards from being stored.'
          ),
        required=False)
    sensitive_fields = forms.CharField(
        label=_('Additional sensitive fields'),
        help_text=
        _('Additional field names to match against when scrubbing data. Separate multiple entries with a newline.'
          ),
        widget=forms.Textarea(
            attrs={
                'placeholder': mark_safe(_('e.g. email')),
                'class': 'span8',
                'rows': '3',
            }),
        required=False,
    )
    scrub_ip_address = forms.BooleanField(
        label=_('Don\'t store IP Addresses'),
        help_text=_('Prevent IP addresses from being stored for new events.'),
        required=False)

    class Meta:
        fields = ('name', 'platform', 'public', 'team', 'slug')
        model = Project

    def __init__(self, request, organization, team_list, data, instance, *args,
                 **kwargs):
        super(EditProjectForm, self).__init__(data=data,
                                              instance=instance,
                                              *args,
                                              **kwargs)

        self.organization = organization
        self.team_list = team_list

        if not can_set_public_projects(request.user):
            del self.fields['public']
        self.fields['team'].choices = self.get_team_choices(
            team_list, instance.team)
        self.fields['team'].widget.choices = self.fields['team'].choices

    def get_team_label(self, team):
        return '%s (%s)' % (team.name, team.slug)

    def get_team_choices(self, team_list, default=None):
        sorted_team_list = sorted(team_list, key=lambda x: x.name)

        choices = []
        for team in sorted_team_list:
            # TODO: optimize queries
            choices.append((team.id, self.get_team_label(team)))

        if default is None:
            choices.insert(0, (-1, mark_safe('–' * 8)))
        elif default not in sorted_team_list:
            choices.insert(0, (default.id, self.get_team_label(default)))

        return choices

    def clean_sensitive_fields(self):
        value = self.cleaned_data.get('sensitive_fields')
        if not value:
            return

        return filter(bool, (v.lower().strip() for v in value.split('\n')))

    def clean_team(self):
        value = self.cleaned_data.get('team')
        if not value:
            return

        # TODO: why is this not already an int?
        value = int(value)
        if value == -1:
            return

        if self.instance.team and value == self.instance.team.id:
            return self.instance.team

        for team in self.team_list:
            if value == team.id:
                return team

        raise forms.ValidationError('Unable to find chosen team')

    def clean_slug(self):
        slug = self.cleaned_data.get('slug')
        if not slug:
            return
        exists_qs = Project.objects.filter(
            slug=slug,
            organization=self.organization).exclude(id=self.instance.id)
        if exists_qs.exists():
            raise forms.ValidationError(
                'Another project is already using that slug')
        return slug
Beispiel #3
0
class PasswordlessRegistrationForm(forms.ModelForm):
    name = forms.CharField(
        label=_('Name'),
        max_length=30,
        widget=forms.TextInput(attrs={'placeholder': 'Jane Doe'}),
        required=True
    )
    username = forms.EmailField(
        label=_('Email'),
        max_length=128,
        widget=forms.TextInput(attrs={'placeholder': '*****@*****.**'}),
        required=True
    )
    subscribe = CustomTypedChoiceField(
        coerce=lambda x: six.text_type(x) == u'1',
        label=_("Email updates"),
        choices=(
            (1, 'Yes, I would like to receive updates via email'),
            (0, "No, I'd prefer not to receive these updates"),
        ),
        widget=forms.RadioSelect,
        required=True,
        initial=False,
    )

    def __init__(self, *args, **kwargs):
        super(PasswordlessRegistrationForm, self).__init__(*args, **kwargs)
        if not newsletter.is_enabled():
            del self.fields['subscribe']
        else:
            # NOTE: the text here is duplicated within the ``NewsletterConsent`` component
            # in the UI
            notice = (
                "We'd love to keep you updated via email with product and feature "
                "announcements, promotions, educational materials, and events. "
                "Our updates focus on relevant information, and we'll never sell "
                "your data to third parties. See our "
                "<a href=\"{privacy_link}\">Privacy Policy</a> for more details."
            )
            self.fields['subscribe'].help_text = mark_safe(
                notice.format(privacy_link=settings.PRIVACY_URL))

    class Meta:
        fields = ('username', 'name')
        model = User

    def clean_username(self):
        value = (self.cleaned_data.get('username') or '').strip()
        if not value:
            return
        if User.objects.filter(username__iexact=value).exists():
            raise forms.ValidationError(
                _('An account is already registered with that email address.'))
        return value.lower()

    def save(self, commit=True):
        user = super(PasswordlessRegistrationForm, self).save(commit=False)
        user.email = user.username
        if commit:
            user.save()
            if self.cleaned_data.get('subscribe'):
                newsletter.create_or_update_subscriptions(
                    user, list_ids=newsletter.get_default_list_ids())
        return user
Beispiel #4
0
class EditProjectForm(forms.ModelForm):
    name = forms.CharField(
        label=_('Project Name'),
        max_length=200,
        widget=forms.TextInput(attrs={'placeholder': _('Production')}))
    platform = forms.ChoiceField(
        choices=Project._meta.get_field('platform').get_choices(
            blank_choice=BLANK_CHOICE),
        widget=forms.Select(
            attrs={'data-placeholder': _('Select a platform')}))
    public = forms.BooleanField(
        required=False,
        help_text=_('Imply public access to any event for this project.'))
    team = CustomTypedChoiceField(choices=(), coerce=int, required=False)
    origins = OriginsField(
        label=_('Allowed Domains'),
        required=False,
        help_text=_('Separate multiple entries with a newline.'))
    resolve_age = RangeField(help_text=_(
        'Treat an event as resolved if it hasn\'t been seen for this amount of time.'
    ),
                             required=False,
                             min_value=0,
                             max_value=168,
                             step_value=1)
    scrub_data = forms.BooleanField(
        label=_('Data Scrubber'),
        help_text=
        _('Apply server-side data scrubbing to prevent things like passwords and credit cards from being stored.'
          ),
        required=False)
    scrub_ip_address = forms.BooleanField(
        label=_('Don\'t store IP Addresses'),
        help_text=_('Prevent IP addresses from being stored for new events.'),
        required=False)

    class Meta:
        fields = ('name', 'platform', 'public', 'team', 'slug')
        model = Project

    def __init__(self, request, team_list, data, instance, *args, **kwargs):
        super(EditProjectForm, self).__init__(data=data,
                                              instance=instance,
                                              *args,
                                              **kwargs)

        self.team_list = team_list

        if not can_set_public_projects(request.user):
            del self.fields['public']
        self.fields['team'].choices = self.get_team_choices(
            team_list, instance.team)
        self.fields['team'].widget.choices = self.fields['team'].choices

    def get_team_label(self, team):
        return '%s (%s)' % (team.name, team.slug)

    def get_team_choices(self, team_list, default=None):
        sorted_team_list = sorted(team_list, key=lambda x: x.name)

        choices = []
        for team in sorted_team_list:
            # TODO: optimize queries
            choices.append((team.id, self.get_team_label(team)))

        if default is None:
            choices.insert(0, (-1, mark_safe('&ndash;' * 8)))
        elif default not in sorted_team_list:
            choices.insert(0, (default.id, self.get_team_label(default)))

        return choices

    def clean_team(self):
        value = self.cleaned_data.get('team')
        if not value:
            return

        # TODO: why is this not already an int?
        value = int(value)
        if value == -1:
            return

        if self.instance.team and value == self.instance.team.id:
            return self.instance.team

        for team in self.team_list:
            if value == team.id:
                return team

        raise forms.ValidationError('Unable to find chosen team')
Beispiel #5
0
class EditProjectForm(forms.ModelForm):
    name = forms.CharField(
        label=_('Project Name'),
        max_length=200,
        widget=forms.TextInput(attrs={'placeholder': _('Production')}))
    slug = forms.SlugField(
        label=_('Short name'),
        help_text=_('A unique ID used to identify this project.'),
    )
    team = CustomTypedChoiceField(choices=(), coerce=int, required=False)
    origins = OriginsField(
        label=_('Allowed Domains'),
        required=False,
        help_text=_('Separate multiple entries with a newline.'))
    token = forms.CharField(
        label=_('Security token'),
        required=True,
        help_text=
        _('Outbound requests matching Allowed Domains will have the header "X-Sentry-Token: {token}" appended.'
          ))
    resolve_age = RangeField(
        label=_('Auto resolve'),
        required=False,
        min_value=0,
        max_value=168,
        step_value=1,
        help_text=
        _('Automatically resolve an issue if it hasn\'t been seen for this amount of time.'
          ))
    scrub_data = forms.BooleanField(
        label=_('Data Scrubber'),
        help_text=_('Enable server-side data scrubbing.'),
        required=False)
    scrub_defaults = forms.BooleanField(
        label=_('Use Default Scrubbers'),
        help_text=
        _('Apply default scrubbers to prevent things like passwords and credit cards from being stored.'
          ),
        required=False)
    sensitive_fields = forms.CharField(
        label=_('Additional sensitive fields'),
        help_text=
        _('Additional field names to match against when scrubbing data. Separate multiple entries with a newline.'
          ),
        widget=forms.Textarea(
            attrs={
                'placeholder': mark_safe(_('e.g. email')),
                'class': 'span8',
                'rows': '3',
            }),
        required=False,
    )
    scrub_ip_address = forms.BooleanField(
        label=_('Don\'t store IP Addresses'),
        help_text=_('Prevent IP addresses from being stored for new events.'),
        required=False)

    # JavaScript options
    scrape_javascript = forms.BooleanField(
        label=_('Enable JavaScript source fetching'),
        help_text=
        _('Allow Sentry to scrape missing JavaScript source context when possible.'
          ),
        required=False,
    )
    blacklisted_ips = IPNetworksField(
        label=_('Filtered IP Addresses'),
        required=False,
        help_text=_('Separate multiple entries with a newline.'))

    # Options that are overridden by Organization level settings
    org_overrides = ('scrub_data', 'scrub_defaults', 'scrub_ip_address')

    default_environment = forms.CharField(
        label=_('Default Environment'),
        help_text=_('The default selected environment when viewing issues.'),
        widget=forms.TextInput(attrs={'placeholder': _('e.g. production')}),
        required=False,
    )

    class Meta:
        fields = ('name', 'team', 'slug')
        model = Project

    def __init__(self, request, organization, team_list, data, instance, *args,
                 **kwargs):
        # First, we need to check for the value overrides from the Organization options
        # We need to do this before `initial` gets passed into the Form.
        disabled = []
        if 'initial' in kwargs:
            for opt in self.org_overrides:
                value = bool(
                    organization.get_option('sentry:require_%s' % (opt, ),
                                            False))
                if value:
                    disabled.append(opt)
                    kwargs['initial'][opt] = value

        super(EditProjectForm, self).__init__(data=data,
                                              instance=instance,
                                              *args,
                                              **kwargs)

        self.organization = organization
        self.team_list = team_list

        self.fields['team'].choices = self.get_team_choices(
            team_list, instance.team)
        self.fields['team'].widget.choices = self.fields['team'].choices

        # After the Form is initialized, we now need to disable the fields that have been
        # overridden from Organization options.
        for opt in disabled:
            self.fields[opt].widget.attrs['disabled'] = 'disabled'

    def get_team_label(self, team):
        return '%s (%s)' % (team.name, team.slug)

    def get_team_choices(self, team_list, default=None):
        sorted_team_list = sorted(team_list, key=lambda x: x.name)

        choices = []
        for team in sorted_team_list:
            # TODO: optimize queries
            choices.append((team.id, self.get_team_label(team)))

        if default is None:
            choices.insert(0, (-1, mark_safe('&ndash;' * 8)))
        elif default not in sorted_team_list:
            choices.insert(0, (default.id, self.get_team_label(default)))

        return choices

    def clean_sensitive_fields(self):
        value = self.cleaned_data.get('sensitive_fields')
        if not value:
            return

        return filter(bool, (v.lower().strip() for v in value.split('\n')))

    def clean_team(self):
        value = self.cleaned_data.get('team')
        if not value:
            return

        # TODO: why is this not already an int?
        value = int(value)
        if value == -1:
            return

        if self.instance.team and value == self.instance.team.id:
            return self.instance.team

        for team in self.team_list:
            if value == team.id:
                return team

        raise forms.ValidationError('Unable to find chosen team')

    def clean_slug(self):
        slug = self.cleaned_data.get('slug')
        if not slug:
            return
        other = Project.objects.filter(slug=slug,
                                       organization=self.organization).exclude(
                                           id=self.instance.id).first()
        if other is not None:
            raise forms.ValidationError('Another project (%s) is already '
                                        'using that slug' % other.name)
        return slug
Beispiel #6
0
class EditProjectForm(forms.ModelForm):
    name = forms.CharField(
        label=_('Project Name'),
        max_length=200,
        widget=forms.TextInput(attrs={'placeholder': _('Production')}))
    slug = forms.SlugField(
        label=_('Short name'),
        help_text=_('A unique ID used to identify this project.'),
    )
    team = CustomTypedChoiceField(choices=(), coerce=int, required=False)
    # add by hzwangzhiwei @20160411
    redmine = forms.CharField(
        label=
        _("Redmine URL ( HOW to: <a href='http://qadoc.nie.netease.com/?/article/28' target='_blank'>http://qadoc.nie.netease.com/?/article/28</a> )"
          ),
        max_length=200,
        required=False,
        widget=forms.TextInput(
            attrs={
                'placeholder':
                _('eg. http://h11.pm.netease.com/projects/h11-bugs/issues/new')
            }))
    # add by hzwangzhiwei @20160922
    redmine_token = forms.CharField(
        label=
        _("RedmineAPI Token ( What: <a href='http://redmineapi.nie.netease.com/home/' target='_blank'>http://redmineapi.nie.netease.com/home/</a> )"
          ),
        max_length=200,
        required=False,
        widget=forms.TextInput(
            attrs={'placeholder': _('eg. 70cfa944be845d3d9219a4a1c51bdba9')}))
    redmine_host = forms.CharField(label=_(
        "RedmineAPI Host ( What: <a href='http://redmineapi.nie.netease.com/home/' target='_blank'>http://redmineapi.nie.netease.com/home/</a> )"
    ),
                                   max_length=200,
                                   required=False,
                                   widget=forms.TextInput(attrs={
                                       'placeholder':
                                       _('eg. hm1.pm.netease.com')
                                   }))

    origins = OriginsField(
        label=_('Allowed Domains'),
        required=False,
        help_text=_('Separate multiple entries with a newline.'))
    token = forms.CharField(
        label=_('Security token'),
        required=True,
        help_text=
        _('Outbound requests matching Allowed Domains will have the header "X-Sentry-Token: {token}" appended.'
          ))
    # for #846 auto solve time, 30 days, add by hzwangzhiwei @20160803
    resolve_age = RangeField(
        label=_('Auto resolve'),
        required=False,
        min_value=0,
        max_value=720,
        step_value=1,
        help_text=
        _('Treat an event as resolved if it hasn\'t been seen for this amount of time.'
          ))
    scrub_data = forms.BooleanField(
        label=_('Data Scrubber'),
        help_text=_('Enable server-side data scrubbing.'),
        required=False)
    scrub_defaults = forms.BooleanField(
        label=_('Use Default Scrubbers'),
        help_text=
        _('Apply default scrubbers to prevent things like passwords and credit cards from being stored.'
          ),
        required=False)
    sensitive_fields = forms.CharField(
        label=_('Additional sensitive fields'),
        help_text=
        _('Additional field names to match against when scrubbing data. Separate multiple entries with a newline.'
          ),
        widget=forms.Textarea(
            attrs={
                'placeholder': mark_safe(_('e.g. email')),
                'class': 'span8',
                'rows': '3',
            }),
        required=False,
    )
    scrub_ip_address = forms.BooleanField(
        label=_('Don\'t store IP Addresses'),
        help_text=_('Prevent IP addresses from being stored for new events.'),
        required=False)
    scrape_javascript = forms.BooleanField(
        label=_('Enable JavaScript source fetching'),
        help_text=
        _('Allow Sentry to scrape missing JavaScript source context when possible.'
          ),
        required=False,
    )
    blacklisted_ips = IPNetworksField(
        label=_('Blacklisted IP Addresses'),
        required=False,
        help_text=_('Separate multiple entries with a newline.'))
    # for #845 add server_name filter, add by hzwangzhiwei @20160802
    allowed_servernames = ServerNameField(
        label=_('Allowed Server Names'),
        required=False,
        help_text=
        _('Server name whitelist, only the trace which has server_name in WhiteList can be save to the server.'
          ))

    class Meta:
        fields = ('name', 'team', 'slug', 'redmine', 'redmine_token',
                  'redmine_host')
        model = Project

    def __init__(self, request, organization, team_list, data, instance, *args,
                 **kwargs):
        super(EditProjectForm, self).__init__(data=data,
                                              instance=instance,
                                              *args,
                                              **kwargs)

        self.organization = organization
        self.team_list = team_list

        self.fields['team'].choices = self.get_team_choices(
            team_list, instance.team)
        self.fields['team'].widget.choices = self.fields['team'].choices

    def get_team_label(self, team):
        return '%s (%s)' % (team.name, team.slug)

    def get_team_choices(self, team_list, default=None):
        sorted_team_list = sorted(team_list, key=lambda x: x.name)

        choices = []
        for team in sorted_team_list:
            # TODO: optimize queries
            choices.append((team.id, self.get_team_label(team)))

        if default is None:
            choices.insert(0, (-1, mark_safe('&ndash;' * 8)))
        elif default not in sorted_team_list:
            choices.insert(0, (default.id, self.get_team_label(default)))

        return choices

    def clean_sensitive_fields(self):
        value = self.cleaned_data.get('sensitive_fields')
        if not value:
            return

        return filter(bool, (v.lower().strip() for v in value.split('\n')))

    def clean_team(self):
        value = self.cleaned_data.get('team')
        if not value:
            return

        # TODO: why is this not already an int?
        value = int(value)
        if value == -1:
            return

        if self.instance.team and value == self.instance.team.id:
            return self.instance.team

        for team in self.team_list:
            if value == team.id:
                return team

        raise forms.ValidationError('Unable to find chosen team')

    def clean_slug(self):
        slug = self.cleaned_data.get('slug')
        if not slug:
            return
        exists_qs = Project.objects.filter(
            slug=slug,
            organization=self.organization).exclude(id=self.instance.id)
        if exists_qs.exists():
            raise forms.ValidationError(
                'Another project is already using that slug')
        return slug

    def clean_redmine(self):
        redmine = self.cleaned_data.get('redmine')
        if not redmine:
            return
        if not redmine.startswith('http://'):  # TODO, url format
            raise forms.ValidationError(
                'Redmine URL must a valid url. (http://qadoc.nie.netease.com/?/article/28)'
            )
        return redmine

    def clean_redmine_token(self):
        redmine_token = self.cleaned_data.get('redmine_token')
        if not redmine_token:
            return
        return redmine_token

    def clean_redmine_host(self):
        redmine_host = self.cleaned_data.get('redmine_host')
        if not redmine_host:
            return
        return redmine_host