# Buggy code
def secret_edit(request, pk):
    secret = get_object_or_404(Secret, pk=pk)

    if request.method == "POST":
        form = forms.SecretForm(request.POST, instance=secret)
        if form.is_valid():
            # Re-encrypt the Secret if a plaintext and session key have been provided.
            session_key = base64.b64decode(request.COOKIES.get("session_key", None))
            if form.cleaned_data["plaintext"] and session_key is not None:
                # Retrieve the master key using the provided session key
                master_key = None
                try:
                    sk = SessionKey.objects.get(userkey__user=request.user)
                    master_key = sk.get_master_key(session_key)
                except SessionKey.DoesNotExist:
                    form.add_error(None, "No session key found for this user.")

                # Create and encrypt the new Secret
                if master_key is not None:
                    secret = form.save(commit=False)
                    secret.plaintext = str(form.cleaned_data["plaintext"])
                    secret.encrypt(master_key)
                    secret.save()
                    messages.success(request, "Modified secret {}.".format(secret))
                    return redirect("secrets:secret", pk=secret.pk)
                else:
                    form.add_error(
                        None, "Invalid session key. Unable to encrypt secret data."
                    )

            # We can't save the plaintext without a session key.
            elif form.cleaned_data["plaintext"]:
                form.add_error(
                    None,
                    "No session key was provided with the request. Unable to encrypt secret data.",
                )

            # If no new plaintext was specified, a session key is not needed.
            else:
                secret = form.save()
                messages.success(request, "Modified secret {}.".format(secret))
                return redirect("secrets:secret", pk=secret.pk)

    else:
        form = forms.SecretForm(instance=secret)

    return render(
        request,
        "secrets/secret_edit.html",
        {
            "secret": secret,
            "form": form,
            "return_url": reverse("secrets:secret", kwargs={"pk": secret.pk}),
        },
    )


# Traceback (TypeError)
Performing system checks...

System check identified no issues (0 silenced).
April 06, 2017 - 01:41:36
Django version 1.11, using settings 'netbox.settings'
Starting development server at http://0.0.0.0:8002/
Quit the server with CONTROL-C.
Internal Server Error: /dcim/devices/9/add-secret/
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/exception.py", line 41, in inner
response = get_response(request)
File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py", line 187, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py", line 185, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/contrib/auth/decorators.py", line 23, in _wrapped_view
return view_func(request, *args, **kwargs)
File "/opt/netbox-2.0-beta2/netbox/secrets/decorators.py", line 22, in wrapped_view
return view(request, *args, **kwargs)
File "/opt/netbox-2.0-beta2/netbox/secrets/views.py", line 83, in secret_add
session_key = base64.b64decode(request.COOKIES.get('session_key', None))
File "/usr/lib/python2.7/base64.py", line 73, in b64decode
return binascii.a2b_base64(s)
TypeError: must be string or buffer, not None
[06/Apr/2017 01:41:47] "POST /dcim/devices/9/add-secret/ HTTP/1.1" 500 85437

# Fixed code
def secret_edit(request, pk):
    secret = get_object_or_404(Secret, pk=pk)
    session_key = get_session_key(request)

    if request.method == "POST":
        form = forms.SecretForm(request.POST, instance=secret)
        if form.is_valid():
            # Re-encrypt the Secret if a plaintext and session key have been provided.
            if form.cleaned_data["plaintext"] and session_key is not None:
                # Retrieve the master key using the provided session key
                master_key = None
                try:
                    sk = SessionKey.objects.get(userkey__user=request.user)
                    master_key = sk.get_master_key(session_key)
                except SessionKey.DoesNotExist:
                    form.add_error(None, "No session key found for this user.")

                # Create and encrypt the new Secret
                if master_key is not None:
                    secret = form.save(commit=False)
                    secret.plaintext = str(form.cleaned_data["plaintext"])
                    secret.encrypt(master_key)
                    secret.save()
                    messages.success(request, "Modified secret {}.".format(secret))
                    return redirect("secrets:secret", pk=secret.pk)
                else:
                    form.add_error(
                        None, "Invalid session key. Unable to encrypt secret data."
                    )

            # We can't save the plaintext without a session key.
            elif form.cleaned_data["plaintext"]:
                form.add_error(
                    None,
                    "No session key was provided with the request. Unable to encrypt secret data.",
                )

            # If no new plaintext was specified, a session key is not needed.
            else:
                secret = form.save()
                messages.success(request, "Modified secret {}.".format(secret))
                return redirect("secrets:secret", pk=secret.pk)

    else:
        form = forms.SecretForm(instance=secret)

    return render(
        request,
        "secrets/secret_edit.html",
        {
            "secret": secret,
            "form": form,
            "return_url": reverse("secrets:secret", kwargs={"pk": secret.pk}),
        },
    )