def edit_oauth_app(request, app_id=None): """Create or edit an OAuth2 application. Args: request (django.http.HttpRequest): The current HTTP request. app_id (int, optional): The ID of the application to edit. If this argument is ``None`` a new application will be edited. Returns: django.http.HttpResponse: The rendered view. """ # If we import this at global scope, it will cause issues with admin sites # being automatically registered. from reviewboard.oauth.admin import ApplicationAdmin if app_id: app = get_object_or_404( Application, pk=app_id, user=request.user, ) form_cls = UserApplicationChangeForm fieldsets = ApplicationAdmin.fieldsets else: app = None form_cls = UserApplicationCreationForm fieldsets = ApplicationAdmin.add_fieldsets if request.method == 'POST': form_data = request.POST.copy() form = form_cls(user=request.user, data=form_data, initial=None, instance=app) if form.is_valid(): app = form.save() if app_id is not None: next_url = OAuth2Page.get_absolute_url() else: next_url = reverse('edit-oauth-app', args=(app.pk, )) return HttpResponseRedirect(next_url) else: form = form_cls(user=request.user, data=None, initial=None, instance=app) # Show a warning at the top of the form when the form is disabled for # security. # # We don't need to worry about full_clean not being called (which would # be if we went through form.errors) because this form will never be # saved. if app and app.is_disabled_for_security: form._errors = ErrorDict({ '__all__': form.error_class([form.DISABLED_FOR_SECURITY_ERROR], ), }) return render_to_response( 'accounts/edit_oauth_app.html', { 'app': app, 'form': form, 'fieldsets': filter_fieldsets(form=form_cls, fieldsets=fieldsets), 'oauth2_page_url': OAuth2Page.get_absolute_url(), 'request': request, })
class ApplicationAdmin(admin.ModelAdmin): """The model admin for the OAuth application model. The default model admin provided by django-oauth-toolkit does not provide help text for the majority of the fields, so this admin uses a custom form which does provide the help text. """ form = ApplicationChangeForm add_form = ApplicationCreationForm raw_id_fields = ('local_site', ) fieldsets = ( (_('General Settings'), { 'fields': ( 'name', 'enabled', 'user', 'redirect_uris', ), }), (_('Client Settings'), { 'fields': ('client_id', 'client_secret', 'client_type'), }), (_('Authorization Settings'), { 'fields': ( 'authorization_grant_type', 'skip_authorization', 'local_site', ), }), (_('Internal State'), { 'description': _('<p>This is advanced state that should not be modified unless ' 'something is wrong.</p>'), 'fields': ('original_user', 'extra_data'), 'classes': ('collapse', ), }), ) add_fieldsets = tuple( filter_fieldsets( form=add_form, fieldsets=fieldsets, exclude_collapsed=False, )) def get_fieldsets(self, request, obj=None): """Return the appropriate fieldset. Args: request (django.http.HttpRequest): The current HTTP request. obj (reviewboard.oauth.models.Application, optional): The application being edited, if it already exists. Returns: tuple: The fieldset for either changing an Application (i.e., when ``obj is not None``) or the fieldset for creating an Application. """ if obj is None: return self.add_fieldsets return super(ApplicationAdmin, self).get_fieldsets(request, obj=obj) def get_form(self, request, obj=None, **kwargs): """Return the form class to use. This method mostly delegates to the superclass, but hints that we should use :py:attr:`add_form` (and its fields) when we are creating the Application. Args: request (django.http.HttpRequest): The current HTTP request. obj (reviewboard.oauth.models.Application, optional): The application being edited, if it exists. Returns: type: The form class to use. """ if obj is None: kwargs = kwargs.copy() kwargs['form'] = self.add_form kwargs['fields'] = flatten_fieldsets(self.add_fieldsets) return super(ApplicationAdmin, self).get_form(request, obj=obj, **kwargs) def response_add(self, request, obj, post_url_continue=None): """Return the response for the ``add_view`` stage. This method will redirect the user to the change form after creating the application. We do this because the ``client_secret`` and ``client_id`` fields are generated by saving the form and it is likely the user will want to view and/or copy them after creating this Application. Args: request (django.http.HttpRequest): The current HTTP request. obj (reviewboard.oauth.models.Application): The application that was created. post_url_continue (unicode, optional): The next URL to go to. Returns: django.http.HttpResponse: A response redirecting the user to the change form. """ if ('_addanother' not in request.POST and IS_POPUP_VAR not in request.POST): # request.POST is immutable on modern versions of Django. The # pattern used within Django for this exact situation is to copy # the dictionary and then modify it. request.POST = request.POST.copy() request.POST['_continue'] = 1 return super(ApplicationAdmin, self).response_add( request, obj, post_url_continue=post_url_continue, )
def edit_oauth_app(request, app_id=None): """Create or edit an OAuth2 application. Args: request (django.http.HttpRequest): The current HTTP request. app_id (int, optional): The ID of the application to edit. If this argument is ``None`` a new application will be edited. Returns: django.http.HttpResponse: The rendered view. """ # If we import this at global scope, it will cause issues with admin sites # being automatically registered. from reviewboard.oauth.admin import ApplicationAdmin if app_id: app = get_object_or_404( Application, pk=app_id, user=request.user, ) form_cls = UserApplicationChangeForm fieldsets = ApplicationAdmin.fieldsets else: app = None form_cls = UserApplicationCreationForm fieldsets = ApplicationAdmin.add_fieldsets if request.method == 'POST': form_data = request.POST.copy() form = form_cls(user=request.user, data=form_data, initial=None, instance=app) if form.is_valid(): app = form.save() if app_id is not None: next_url = OAuth2Page.get_absolute_url() else: next_url = reverse('edit-oauth-app', args=(app.pk,)) return HttpResponseRedirect(next_url) else: form = form_cls(user=request.user, data=None, initial=None, instance=app) # Show a warning at the top of the form when the form is disabled for # security. # # We don't need to worry about full_clean not being called (which would # be if we went through form.errors) because this form will never be # saved. if app and app.is_disabled_for_security: form._errors = ErrorDict({ '__all__': form.error_class( [form.DISABLED_FOR_SECURITY_ERROR], ), }) return render_to_response( 'accounts/edit_oauth_app.html', { 'app': app, 'form': form, 'fieldsets': filter_fieldsets(form=form_cls, fieldsets=fieldsets), 'oauth2_page_url': OAuth2Page.get_absolute_url(), 'request': request, })