prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Create documentation section for explaining certificates, signing and how it all works together
  App devs need a very quick tutorial/walkthrough in the docs on how to generate a new certificate pair, request the public cert to be signed, registering an app id, revoking certs (like registering certs: post it on our issue tracker) and signing apps.
  
  Also some background needs to be provided on how the whole certificate mechanism works.
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `nextcloudappstore/core/forms.py`
  Content:
  ```
  1 from django.forms import Form, CharField, Textarea, ChoiceField, RadioSelect, \
  2     BooleanField
  3 from django.utils.translation import ugettext_lazy as _  # type: ignore
  4 
  5 from nextcloudappstore.core.models import App, AppRating
  6 
  7 RATING_CHOICES = (
  8     (0.0, _('Bad')),
  9     (0.5, _('Ok')),
  10     (1.0, _('Good'))
  11 )
  12 
  13 
  14 class AppReleaseUploadForm(Form):
  15     download = CharField(label=_('Download link (tar.gz)'), max_length=256)
  16     signature = CharField(widget=Textarea, label=_('SHA512 signature'),
  17                           help_text=_(
  18                               'Hint: can be calculated by executing the '
  19                               'following command: openssl dgst -sha512 -sign '
  20                               '/path/to/private-cert.key /path/to/app.tar.gz '
  21                               '| openssl base64'))
  22     nightly = BooleanField(label=_('Nightly'))
  23 
  24 
  25 class AppRatingForm(Form):
  26     def __init__(self, *args, **kwargs):
  27         self._id = kwargs.pop('id', None)
  28         self._user = kwargs.pop('user', None)
  29         self._language_code = kwargs.pop('language_code', None)
  30         super().__init__(*args, **kwargs)
  31 
  32     rating = ChoiceField(initial=0.5, choices=RATING_CHOICES,
  33                          widget=RadioSelect)
  34     comment = CharField(widget=Textarea, required=False,
  35                         label=_('Review'))
  36 
  37     class Meta:
  38         fields = ('rating', 'comment')
  39 
  40     def save(self):
  41         app = App.objects.get(id=self._id)
  42         app_rating, created = AppRating.objects.get_or_create(user=self._user,
  43                                                               app=app)
  44         app_rating.rating = self.cleaned_data['rating']
  45         app_rating.set_current_language(self._language_code)
  46         app_rating.comment = self.cleaned_data['comment']
  47         app_rating.save()
  48
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/nextcloudappstore/core/forms.py b/nextcloudappstore/core/forms.py
  --- a/nextcloudappstore/core/forms.py
  +++ b/nextcloudappstore/core/forms.py
  @@ -13,15 +13,32 @@
   
   class AppReleaseUploadForm(Form):
       download = CharField(label=_('Download link (tar.gz)'), max_length=256)
  -    signature = CharField(widget=Textarea, label=_('SHA512 signature'),
  -                          help_text=_(
  -                              'Hint: can be calculated by executing the '
  -                              'following command: openssl dgst -sha512 -sign '
  -                              '/path/to/private-cert.key /path/to/app.tar.gz '
  -                              '| openssl base64'))
  +    signature = CharField(
  +        widget=Textarea,
  +        label=_('SHA512 signature'),
  +        help_text=_(
  +            'Hint: can be calculated by executing the '
  +            'following command: openssl dgst -sha512 -sign '
  +            '~/.nextcloud/certificates/APP_ID.key '
  +            '/path/to/app.tar.gz | openssl base64'))
       nightly = BooleanField(label=_('Nightly'))
   
   
  +class AppRegisterForm(Form):
  +    certificate = CharField(
  +        widget=Textarea(attrs={'pattern': '-----BEGIN CERTIFICATE-----.*'}),
  +        label=_('Public certificate'),
  +        help_text=_(
  +            'Usually stored in ~/.nextcloud/certificates/APP_ID.crt'))
  +    signature = CharField(
  +        widget=Textarea,
  +        label=_('SHA512 signature'),
  +        help_text=_(
  +            'Hint: can be calculated by executing the '
  +            'following command: echo -n "APP_ID" | openssl dgst -sha512 -sign '
  +            '~/.nextcloud/certificates/APP_ID.key | openssl base64'))
  +
  +
   class AppRatingForm(Form):
       def __init__(self, *args, **kwargs):
           self._id = kwargs.pop('id', None)
  
verification_info: {"golden_diff": "diff --git a/nextcloudappstore/core/forms.py b/nextcloudappstore/core/forms.py\n--- a/nextcloudappstore/core/forms.py\n+++ b/nextcloudappstore/core/forms.py\n@@ -13,15 +13,32 @@\n \n class AppReleaseUploadForm(Form):\n     download = CharField(label=_('Download link (tar.gz)'), max_length=256)\n-    signature = CharField(widget=Textarea, label=_('SHA512 signature'),\n-                          help_text=_(\n-                              'Hint: can be calculated by executing the '\n-                              'following command: openssl dgst -sha512 -sign '\n-                              '/path/to/private-cert.key /path/to/app.tar.gz '\n-                              '| openssl base64'))\n+    signature = CharField(\n+        widget=Textarea,\n+        label=_('SHA512 signature'),\n+        help_text=_(\n+            'Hint: can be calculated by executing the '\n+            'following command: openssl dgst -sha512 -sign '\n+            '~/.nextcloud/certificates/APP_ID.key '\n+            '/path/to/app.tar.gz | openssl base64'))\n     nightly = BooleanField(label=_('Nightly'))\n \n \n+class AppRegisterForm(Form):\n+    certificate = CharField(\n+        widget=Textarea(attrs={'pattern': '-----BEGIN CERTIFICATE-----.*'}),\n+        label=_('Public certificate'),\n+        help_text=_(\n+            'Usually stored in ~/.nextcloud/certificates/APP_ID.crt'))\n+    signature = CharField(\n+        widget=Textarea,\n+        label=_('SHA512 signature'),\n+        help_text=_(\n+            'Hint: can be calculated by executing the '\n+            'following command: echo -n \"APP_ID\" | openssl dgst -sha512 -sign '\n+            '~/.nextcloud/certificates/APP_ID.key | openssl base64'))\n+\n+\n class AppRatingForm(Form):\n     def __init__(self, *args, **kwargs):\n         self._id = kwargs.pop('id', None)\n", "issue": "Create documentation section for explaining certificates, signing and how it all works together\nApp devs need a very quick tutorial/walkthrough in the docs on how to generate a new certificate pair, request the public cert to be signed, registering an app id, revoking certs (like registering certs: post it on our issue tracker) and signing apps.\n\nAlso some background needs to be provided on how the whole certificate mechanism works.\n\n", "before_files": [{"content": "from django.forms import Form, CharField, Textarea, ChoiceField, RadioSelect, \\\n    BooleanField\nfrom django.utils.translation import ugettext_lazy as _  # type: ignore\n\nfrom nextcloudappstore.core.models import App, AppRating\n\nRATING_CHOICES = (\n    (0.0, _('Bad')),\n    (0.5, _('Ok')),\n    (1.0, _('Good'))\n)\n\n\nclass AppReleaseUploadForm(Form):\n    download = CharField(label=_('Download link (tar.gz)'), max_length=256)\n    signature = CharField(widget=Textarea, label=_('SHA512 signature'),\n                          help_text=_(\n                              'Hint: can be calculated by executing the '\n                              'following command: openssl dgst -sha512 -sign '\n                              '/path/to/private-cert.key /path/to/app.tar.gz '\n                              '| openssl base64'))\n    nightly = BooleanField(label=_('Nightly'))\n\n\nclass AppRatingForm(Form):\n    def __init__(self, *args, **kwargs):\n        self._id = kwargs.pop('id', None)\n        self._user = kwargs.pop('user', None)\n        self._language_code = kwargs.pop('language_code', None)\n        super().__init__(*args, **kwargs)\n\n    rating = ChoiceField(initial=0.5, choices=RATING_CHOICES,\n                         widget=RadioSelect)\n    comment = CharField(widget=Textarea, required=False,\n                        label=_('Review'))\n\n    class Meta:\n        fields = ('rating', 'comment')\n\n    def save(self):\n        app = App.objects.get(id=self._id)\n        app_rating, created = AppRating.objects.get_or_create(user=self._user,\n                                                              app=app)\n        app_rating.rating = self.cleaned_data['rating']\n        app_rating.set_current_language(self._language_code)\n        app_rating.comment = self.cleaned_data['comment']\n        app_rating.save()\n", "path": "nextcloudappstore/core/forms.py"}], "after_files": [{"content": "from django.forms import Form, CharField, Textarea, ChoiceField, RadioSelect, \\\n    BooleanField\nfrom django.utils.translation import ugettext_lazy as _  # type: ignore\n\nfrom nextcloudappstore.core.models import App, AppRating\n\nRATING_CHOICES = (\n    (0.0, _('Bad')),\n    (0.5, _('Ok')),\n    (1.0, _('Good'))\n)\n\n\nclass AppReleaseUploadForm(Form):\n    download = CharField(label=_('Download link (tar.gz)'), max_length=256)\n    signature = CharField(\n        widget=Textarea,\n        label=_('SHA512 signature'),\n        help_text=_(\n            'Hint: can be calculated by executing the '\n            'following command: openssl dgst -sha512 -sign '\n            '~/.nextcloud/certificates/APP_ID.key '\n            '/path/to/app.tar.gz | openssl base64'))\n    nightly = BooleanField(label=_('Nightly'))\n\n\nclass AppRegisterForm(Form):\n    certificate = CharField(\n        widget=Textarea(attrs={'pattern': '-----BEGIN CERTIFICATE-----.*'}),\n        label=_('Public certificate'),\n        help_text=_(\n            'Usually stored in ~/.nextcloud/certificates/APP_ID.crt'))\n    signature = CharField(\n        widget=Textarea,\n        label=_('SHA512 signature'),\n        help_text=_(\n            'Hint: can be calculated by executing the '\n            'following command: echo -n \"APP_ID\" | openssl dgst -sha512 -sign '\n            '~/.nextcloud/certificates/APP_ID.key | openssl base64'))\n\n\nclass AppRatingForm(Form):\n    def __init__(self, *args, **kwargs):\n        self._id = kwargs.pop('id', None)\n        self._user = kwargs.pop('user', None)\n        self._language_code = kwargs.pop('language_code', None)\n        super().__init__(*args, **kwargs)\n\n    rating = ChoiceField(initial=0.5, choices=RATING_CHOICES,\n                         widget=RadioSelect)\n    comment = CharField(widget=Textarea, required=False,\n                        label=_('Review'))\n\n    class Meta:\n        fields = ('rating', 'comment')\n\n    def save(self):\n        app = App.objects.get(id=self._id)\n        app_rating, created = AppRating.objects.get_or_create(user=self._user,\n                                                              app=app)\n        app_rating.rating = self.cleaned_data['rating']\n        app_rating.set_current_language(self._language_code)\n        app_rating.comment = self.cleaned_data['comment']\n        app_rating.save()\n", "path": "nextcloudappstore/core/forms.py"}]}