We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Permissions: Renaming a permission group is not possible
Existing groups cannot be renamed.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `login/views.py`
Content:
```
1 from django import forms
2 from django.contrib.auth import update_session_auth_hash
3 from django.contrib.auth.mixins import LoginRequiredMixin
4 from django.contrib.auth.models import Group
5 from django.contrib.auth.views import PasswordChangeView, PasswordResetView
6 from django.core.exceptions import ObjectDoesNotExist, PermissionDenied
7 from django.http import Http404
8 from django.shortcuts import get_object_or_404, redirect, render
9 from django.views.generic import FormView, View
10 from django.views.generic.edit import UpdateView
11 
12 import login.models as models
13 
14 from .forms import ChangeEmailForm, CreateUserForm, DetachForm, EditUserForm, GroupForm
15 from .models import ADMIN_PERM, GroupMembership, UserGroup
16 from .models import myuser as OepUser
17 
18 from oeplatform.settings import URL
19 
20 class ProfileView(View):
21     def get(self, request, user_id):
22         """
23         Load the user identified by user_id and is OAuth-token. If latter does not exist yet, create one.
24         :param request: A HTTP-request object sent by the Django framework.
25         :param user_id: An user id
26         :return: Profile renderer
27         """
28         from rest_framework.authtoken.models import Token
29 
30         for user in OepUser.objects.all():
31             Token.objects.get_or_create(user=user)
32         user = get_object_or_404(OepUser, pk=user_id)
33         token = None
34         if request.user.is_authenticated:
35             token = Token.objects.get(user=request.user)
36         return render(
37             request, "login/profile.html", {"profile_user": user, "token": token}
38         )
39 
40 
41 class GroupManagement(View, LoginRequiredMixin):
42     def get(self, request):
43         """
44         Load and list the available groups by groupadmin. 
45         :param request: A HTTP-request object sent by the Django framework.
46         :param user_id: An user id
47         :return: Profile renderer   
48         """
49 
50         membership = request.user.memberships
51         return render(
52             request, "login/list_memberships.html", {"membership": membership}
53         )
54 
55 
56 class GroupCreate(View, LoginRequiredMixin):
57     def get(self, request, group_id=None):
58         """
59         Load the chosen action(create or edit) for a group.
60         :param request: A HTTP-request object sent by the Django framework.
61         :param user_id: An user id
62         :param user_id: An group id
63         :return: Profile renderer
64         """
65 
66         if group_id:
67             group = UserGroup.objects.get(id=group_id)
68             form = GroupForm(instance=group)
69             membership = get_object_or_404(
70                 GroupMembership, group=group, user=request.user
71             )
72             if membership.level < ADMIN_PERM:
73                 raise PermissionDenied
74         else:
75             form = GroupForm()
76         return render(request, "login/group_create.html", {"form": form})
77 
78     def post(self, request, group_id=None):
79         """
80         Performs selected action(save or delete) for a group. If a groupname already exists, then a error
81         will be output.
82         The selected users become members of this group. The groupadmin is already set.
83         :param request: A HTTP-request object sent by the Django framework.
84         :param user_id: An user id
85         :param user_id: An group id
86         :return: Profile renderer
87         """
88         group = UserGroup.objects.get(id=group_id) if group_id else None
89         form = GroupForm(request.POST, instance=group)
90         if form.is_valid():
91             if group_id:
92                 membership = get_object_or_404(
93                     GroupMembership, group=group, user=request.user
94                 )
95                 if membership.level < ADMIN_PERM:
96                     raise PermissionDenied
97             else:
98                 group = form.save()
99                 membership = GroupMembership.objects.create(
100                     user=request.user, group=group, level=ADMIN_PERM
101                 )
102                 membership.save()
103             return redirect("/user/groups/{id}".format(id=group.id), {"group": group})
104         else:
105             return render(request, "login/group_create.html", {"form": form})
106 
107 
108 class GroupView(View, LoginRequiredMixin):
109     def get(self, request, group_id):
110         """
111         Load the chosen action(create or edit) for a group.
112         :param request: A HTTP-request object sent by the Django framework.
113         :param user_id: An user id
114         :param user_id: An group id
115         :return: Profile renderer
116         """
117         group = get_object_or_404(UserGroup, pk=group_id)
118         return render(
119             request,
120             "login/group.html",
121             {"group": group},
122         )
123 
124 
125 class GroupEdit(View, LoginRequiredMixin):
126     def get(self, request, group_id):
127         """
128         Load the chosen action(create or edit) for a group. 
129         :param request: A HTTP-request object sent by the Django framework.
130         :param user_id: An user id
131         :param user_id: An group id
132         :return: Profile renderer   
133         """
134         group = get_object_or_404(UserGroup, pk=group_id)
135         is_admin = False
136         membership = GroupMembership.objects.filter(
137             group=group, user=request.user
138         ).first()
139         if membership:
140             is_admin = membership.level >= ADMIN_PERM
141         return render(
142             request,
143             "login/change_form.html",
144             {"group": group, "choices": GroupMembership.choices, "is_admin": is_admin},
145         )
146 
147     def post(self, request, group_id):
148         """
149         Performs selected action(save or delete) for a group. If a groupname already exists, then a error 
150         will be output. 
151         The selected users become members of this group. The groupadmin is already set.
152         :param request: A HTTP-request object sent by the Django framework.
153         :param user_id: An user id
154         :param user_id: An group id
155         :return: Profile renderer   
156         """
157         mode = request.POST["mode"]
158         group = get_object_or_404(UserGroup, id=group_id)
159         membership = get_object_or_404(GroupMembership, group=group, user=request.user)
160 
161         errors = {}
162         if mode == "add_user":
163             if membership.level < models.WRITE_PERM:
164                 raise PermissionDenied
165             try:
166                 user = OepUser.objects.get(name=request.POST["name"])
167                 membership, _ = GroupMembership.objects.get_or_create(
168                     group=group, user=user
169                 )
170                 membership.save()
171             except OepUser.DoesNotExist:
172                 errors["name"] = "User does not exist"
173         elif mode == "remove_user":
174             if membership.level < models.DELETE_PERM:
175                 raise PermissionDenied
176             user = OepUser.objects.get(id=request.POST["user_id"])
177             membership = GroupMembership.objects.get(group=group, user=user)
178             if membership.level >= ADMIN_PERM:
179                 admins = GroupMembership.objects.filter(group=group).exclude(user=user)
180                 if not admins:
181                     errors["name"] = "A group needs at least one admin"
182                 else:
183                     membership.delete()
184             else:
185                 membership.delete()
186         elif mode == "alter_user":
187             if membership.level < models.ADMIN_PERM:
188                 raise PermissionDenied
189             user = OepUser.objects.get(id=request.POST["user_id"])
190             if user == request.user:
191                 errors["name"] = "You can not change your own permissions"
192             else:
193                 membership = GroupMembership.objects.get(group=group, user=user)
194                 membership.level = request.POST["level"]
195                 membership.save()
196         elif mode == "delete_group":
197             if membership.level < models.ADMIN_PERM:
198                 raise PermissionDenied
199             group.delete()
200             return redirect("/user/groups")
201         else:
202             raise PermissionDenied
203         return render(
204             request,
205             "login/change_form.html",
206             {
207                 "group": group,
208                 "choices": GroupMembership.choices,
209                 "errors": errors,
210                 "is_admin": True,
211             },
212         )
213 
214     def __add_user(self, request, group):
215         user = OepUser.objects.filter(id=request.POST["user_id"]).first()
216         g = user.groups.add(group)
217         g.save()
218         return self.get(request)
219 
220 
221 class ProfileUpdateView(UpdateView, LoginRequiredMixin):
222     """
223     Autogenerate a update form for users.
224     """
225 
226     model = OepUser
227     fields = ["name", "affiliation", "email"]
228     template_name_suffix = "_update_form"
229 
230 
231 class EditUserView(View):
232     def get(self, request, user_id):
233         if not request.user.id == int(user_id):
234             raise PermissionDenied
235         form = EditUserForm(instance=request.user)
236         return render(request, "login/oepuser_edit_form.html", {"form": form})
237 
238     def post(self, request, user_id):
239         if not request.user.id == int(user_id):
240             raise PermissionDenied
241         form = EditUserForm(request.POST, instance=request.user)
242         if form.is_valid():
243             form.save()
244             return redirect("/user/profile/{id}".format(id=request.user.id))
245         else:
246             return render(request, "login/oepuser_edit_form.html", {"form": form})
247 
248 
249 class CreateUserView(View):
250     def get(self, request):
251         form = CreateUserForm()
252         return render(request, "login/oepuser_create_form.html", {"form": form})
253 
254     def post(self, request):
255         form = CreateUserForm(request.POST)
256         if form.is_valid():
257             user = form.save()
258             return redirect("activate")
259         else:
260             return render(request, "login/oepuser_create_form.html", {"form": form})
261 
262 
263 class DetachView(LoginRequiredMixin, View):
264     def get(self, request):
265         if request.user.is_native:
266             raise PermissionDenied
267         form = DetachForm(request.user)
268         return render(request, "login/detach.html", {"form": form})
269 
270     def post(self, request):
271         if request.user.is_native:
272             raise PermissionDenied
273         form = DetachForm(request.user, request.POST)
274         if form.is_valid():
275             form.save()
276             return redirect("/")
277         else:
278             print(form.errors)
279             return render(request, "login/detach.html", {"form": form})
280 
281 
282 class OEPPasswordChangeView(PasswordChangeView):
283     template_name = "login/generic_form.html"
284     success_url = "/"
285 
286 
287 class ActivationNoteView(FormView):
288     template_name = "login/activate.html"
289     form_class = ChangeEmailForm
290     success_url = "user/activate"
291 
292     def form_valid(self, form):
293         if self.request.user.is_anonymous or self.request.user.is_mail_verified:
294             raise PermissionDenied
295         form.save(self.request.user)
296         return super(ActivationNoteView, self).form_valid(form)
297 
298 
299 def activate(request, token):
300     token_obj = models.ActivationToken.objects.filter(value=token).first()
301     if not token_obj:
302         form = ChangeEmailForm()
303         form._errors = {
304             forms.forms.NON_FIELD_ERRORS: form.error_class(
305                 ["Your token was invalid or expired"]
306             )
307         }
308         return render(request, "login/activate.html", {"form": form})
309     else:
310         token_obj.user.is_mail_verified = True
311         token_obj.user.save()
312         token_obj.delete()
313     return redirect("/user/profile/{id}".format(id=token_obj.user.id))
314
```
--- 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()

```

diff --git a/login/views.py b/login/views.py
--- a/login/views.py
+++ b/login/views.py
@@ -89,6 +89,7 @@
         form = GroupForm(request.POST, instance=group)
         if form.is_valid():
             if group_id:
+                group = form.save()
                 membership = get_object_or_404(
                     GroupMembership, group=group, user=request.user
                 )

{"golden_diff": "diff --git a/login/views.py b/login/views.py\n--- a/login/views.py\n+++ b/login/views.py\n@@ -89,6 +89,7 @@\n         form = GroupForm(request.POST, instance=group)\n         if form.is_valid():\n             if group_id:\n+                group = form.save()\n                 membership = get_object_or_404(\n                     GroupMembership, group=group, user=request.user\n                 )\n", "issue": "Permissions: Renaming a permission group is not possible\nExisting groups cannot be renamed.\n", "before_files": [{"content": "from django import forms\nfrom django.contrib.auth import update_session_auth_hash\nfrom django.contrib.auth.mixins import LoginRequiredMixin\nfrom django.contrib.auth.models import Group\nfrom django.contrib.auth.views import PasswordChangeView, PasswordResetView\nfrom django.core.exceptions import ObjectDoesNotExist, PermissionDenied\nfrom django.http import Http404\nfrom django.shortcuts import get_object_or_404, redirect, render\nfrom django.views.generic import FormView, View\nfrom django.views.generic.edit import UpdateView\n\nimport login.models as models\n\nfrom .forms import ChangeEmailForm, CreateUserForm, DetachForm, EditUserForm, GroupForm\nfrom .models import ADMIN_PERM, GroupMembership, UserGroup\nfrom .models import myuser as OepUser\n\nfrom oeplatform.settings import URL\n\nclass ProfileView(View):\n    def get(self, request, user_id):\n        \"\"\"\n        Load the user identified by user_id and is OAuth-token. If latter does not exist yet, create one.\n        :param request: A HTTP-request object sent by the Django framework.\n        :param user_id: An user id\n        :return: Profile renderer\n        \"\"\"\n        from rest_framework.authtoken.models import Token\n\n        for user in OepUser.objects.all():\n            Token.objects.get_or_create(user=user)\n        user = get_object_or_404(OepUser, pk=user_id)\n        token = None\n        if request.user.is_authenticated:\n            token = Token.objects.get(user=request.user)\n        return render(\n            request, \"login/profile.html\", {\"profile_user\": user, \"token\": token}\n        )\n\n\nclass GroupManagement(View, LoginRequiredMixin):\n    def get(self, request):\n        \"\"\"\n        Load and list the available groups by groupadmin. \n        :param request: A HTTP-request object sent by the Django framework.\n        :param user_id: An user id\n        :return: Profile renderer   \n        \"\"\"\n\n        membership = request.user.memberships\n        return render(\n            request, \"login/list_memberships.html\", {\"membership\": membership}\n        )\n\n\nclass GroupCreate(View, LoginRequiredMixin):\n    def get(self, request, group_id=None):\n        \"\"\"\n        Load the chosen action(create or edit) for a group.\n        :param request: A HTTP-request object sent by the Django framework.\n        :param user_id: An user id\n        :param user_id: An group id\n        :return: Profile renderer\n        \"\"\"\n\n        if group_id:\n            group = UserGroup.objects.get(id=group_id)\n            form = GroupForm(instance=group)\n            membership = get_object_or_404(\n                GroupMembership, group=group, user=request.user\n            )\n            if membership.level < ADMIN_PERM:\n                raise PermissionDenied\n        else:\n            form = GroupForm()\n        return render(request, \"login/group_create.html\", {\"form\": form})\n\n    def post(self, request, group_id=None):\n        \"\"\"\n        Performs selected action(save or delete) for a group. If a groupname already exists, then a error\n        will be output.\n        The selected users become members of this group. The groupadmin is already set.\n        :param request: A HTTP-request object sent by the Django framework.\n        :param user_id: An user id\n        :param user_id: An group id\n        :return: Profile renderer\n        \"\"\"\n        group = UserGroup.objects.get(id=group_id) if group_id else None\n        form = GroupForm(request.POST, instance=group)\n        if form.is_valid():\n            if group_id:\n                membership = get_object_or_404(\n                    GroupMembership, group=group, user=request.user\n                )\n                if membership.level < ADMIN_PERM:\n                    raise PermissionDenied\n            else:\n                group = form.save()\n                membership = GroupMembership.objects.create(\n                    user=request.user, group=group, level=ADMIN_PERM\n                )\n                membership.save()\n            return redirect(\"/user/groups/{id}\".format(id=group.id), {\"group\": group})\n        else:\n            return render(request, \"login/group_create.html\", {\"form\": form})\n\n\nclass GroupView(View, LoginRequiredMixin):\n    def get(self, request, group_id):\n        \"\"\"\n        Load the chosen action(create or edit) for a group.\n        :param request: A HTTP-request object sent by the Django framework.\n        :param user_id: An user id\n        :param user_id: An group id\n        :return: Profile renderer\n        \"\"\"\n        group = get_object_or_404(UserGroup, pk=group_id)\n        return render(\n            request,\n            \"login/group.html\",\n            {\"group\": group},\n        )\n\n\nclass GroupEdit(View, LoginRequiredMixin):\n    def get(self, request, group_id):\n        \"\"\"\n        Load the chosen action(create or edit) for a group. \n        :param request: A HTTP-request object sent by the Django framework.\n        :param user_id: An user id\n        :param user_id: An group id\n        :return: Profile renderer   \n        \"\"\"\n        group = get_object_or_404(UserGroup, pk=group_id)\n        is_admin = False\n        membership = GroupMembership.objects.filter(\n            group=group, user=request.user\n        ).first()\n        if membership:\n            is_admin = membership.level >= ADMIN_PERM\n        return render(\n            request,\n            \"login/change_form.html\",\n            {\"group\": group, \"choices\": GroupMembership.choices, \"is_admin\": is_admin},\n        )\n\n    def post(self, request, group_id):\n        \"\"\"\n        Performs selected action(save or delete) for a group. If a groupname already exists, then a error \n        will be output. \n        The selected users become members of this group. The groupadmin is already set.\n        :param request: A HTTP-request object sent by the Django framework.\n        :param user_id: An user id\n        :param user_id: An group id\n        :return: Profile renderer   \n        \"\"\"\n        mode = request.POST[\"mode\"]\n        group = get_object_or_404(UserGroup, id=group_id)\n        membership = get_object_or_404(GroupMembership, group=group, user=request.user)\n\n        errors = {}\n        if mode == \"add_user\":\n            if membership.level < models.WRITE_PERM:\n                raise PermissionDenied\n            try:\n                user = OepUser.objects.get(name=request.POST[\"name\"])\n                membership, _ = GroupMembership.objects.get_or_create(\n                    group=group, user=user\n                )\n                membership.save()\n            except OepUser.DoesNotExist:\n                errors[\"name\"] = \"User does not exist\"\n        elif mode == \"remove_user\":\n            if membership.level < models.DELETE_PERM:\n                raise PermissionDenied\n            user = OepUser.objects.get(id=request.POST[\"user_id\"])\n            membership = GroupMembership.objects.get(group=group, user=user)\n            if membership.level >= ADMIN_PERM:\n                admins = GroupMembership.objects.filter(group=group).exclude(user=user)\n                if not admins:\n                    errors[\"name\"] = \"A group needs at least one admin\"\n                else:\n                    membership.delete()\n            else:\n                membership.delete()\n        elif mode == \"alter_user\":\n            if membership.level < models.ADMIN_PERM:\n                raise PermissionDenied\n            user = OepUser.objects.get(id=request.POST[\"user_id\"])\n            if user == request.user:\n                errors[\"name\"] = \"You can not change your own permissions\"\n            else:\n                membership = GroupMembership.objects.get(group=group, user=user)\n                membership.level = request.POST[\"level\"]\n                membership.save()\n        elif mode == \"delete_group\":\n            if membership.level < models.ADMIN_PERM:\n                raise PermissionDenied\n            group.delete()\n            return redirect(\"/user/groups\")\n        else:\n            raise PermissionDenied\n        return render(\n            request,\n            \"login/change_form.html\",\n            {\n                \"group\": group,\n                \"choices\": GroupMembership.choices,\n                \"errors\": errors,\n                \"is_admin\": True,\n            },\n        )\n\n    def __add_user(self, request, group):\n        user = OepUser.objects.filter(id=request.POST[\"user_id\"]).first()\n        g = user.groups.add(group)\n        g.save()\n        return self.get(request)\n\n\nclass ProfileUpdateView(UpdateView, LoginRequiredMixin):\n    \"\"\"\n    Autogenerate a update form for users.\n    \"\"\"\n\n    model = OepUser\n    fields = [\"name\", \"affiliation\", \"email\"]\n    template_name_suffix = \"_update_form\"\n\n\nclass EditUserView(View):\n    def get(self, request, user_id):\n        if not request.user.id == int(user_id):\n            raise PermissionDenied\n        form = EditUserForm(instance=request.user)\n        return render(request, \"login/oepuser_edit_form.html\", {\"form\": form})\n\n    def post(self, request, user_id):\n        if not request.user.id == int(user_id):\n            raise PermissionDenied\n        form = EditUserForm(request.POST, instance=request.user)\n        if form.is_valid():\n            form.save()\n            return redirect(\"/user/profile/{id}\".format(id=request.user.id))\n        else:\n            return render(request, \"login/oepuser_edit_form.html\", {\"form\": form})\n\n\nclass CreateUserView(View):\n    def get(self, request):\n        form = CreateUserForm()\n        return render(request, \"login/oepuser_create_form.html\", {\"form\": form})\n\n    def post(self, request):\n        form = CreateUserForm(request.POST)\n        if form.is_valid():\n            user = form.save()\n            return redirect(\"activate\")\n        else:\n            return render(request, \"login/oepuser_create_form.html\", {\"form\": form})\n\n\nclass DetachView(LoginRequiredMixin, View):\n    def get(self, request):\n        if request.user.is_native:\n            raise PermissionDenied\n        form = DetachForm(request.user)\n        return render(request, \"login/detach.html\", {\"form\": form})\n\n    def post(self, request):\n        if request.user.is_native:\n            raise PermissionDenied\n        form = DetachForm(request.user, request.POST)\n        if form.is_valid():\n            form.save()\n            return redirect(\"/\")\n        else:\n            print(form.errors)\n            return render(request, \"login/detach.html\", {\"form\": form})\n\n\nclass OEPPasswordChangeView(PasswordChangeView):\n    template_name = \"login/generic_form.html\"\n    success_url = \"/\"\n\n\nclass ActivationNoteView(FormView):\n    template_name = \"login/activate.html\"\n    form_class = ChangeEmailForm\n    success_url = \"user/activate\"\n\n    def form_valid(self, form):\n        if self.request.user.is_anonymous or self.request.user.is_mail_verified:\n            raise PermissionDenied\n        form.save(self.request.user)\n        return super(ActivationNoteView, self).form_valid(form)\n\n\ndef activate(request, token):\n    token_obj = models.ActivationToken.objects.filter(value=token).first()\n    if not token_obj:\n        form = ChangeEmailForm()\n        form._errors = {\n            forms.forms.NON_FIELD_ERRORS: form.error_class(\n                [\"Your token was invalid or expired\"]\n            )\n        }\n        return render(request, \"login/activate.html\", {\"form\": form})\n    else:\n        token_obj.user.is_mail_verified = True\n        token_obj.user.save()\n        token_obj.delete()\n    return redirect(\"/user/profile/{id}\".format(id=token_obj.user.id))\n", "path": "login/views.py"}], "after_files": [{"content": "from django import forms\nfrom django.contrib.auth import update_session_auth_hash\nfrom django.contrib.auth.mixins import LoginRequiredMixin\nfrom django.contrib.auth.models import Group\nfrom django.contrib.auth.views import PasswordChangeView, PasswordResetView\nfrom django.core.exceptions import ObjectDoesNotExist, PermissionDenied\nfrom django.http import Http404\nfrom django.shortcuts import get_object_or_404, redirect, render\nfrom django.views.generic import FormView, View\nfrom django.views.generic.edit import UpdateView\n\nimport login.models as models\n\nfrom .forms import ChangeEmailForm, CreateUserForm, DetachForm, EditUserForm, GroupForm\nfrom .models import ADMIN_PERM, GroupMembership, UserGroup\nfrom .models import myuser as OepUser\n\nfrom oeplatform.settings import URL\n\nclass ProfileView(View):\n    def get(self, request, user_id):\n        \"\"\"\n        Load the user identified by user_id and is OAuth-token. If latter does not exist yet, create one.\n        :param request: A HTTP-request object sent by the Django framework.\n        :param user_id: An user id\n        :return: Profile renderer\n        \"\"\"\n        from rest_framework.authtoken.models import Token\n\n        for user in OepUser.objects.all():\n            Token.objects.get_or_create(user=user)\n        user = get_object_or_404(OepUser, pk=user_id)\n        token = None\n        if request.user.is_authenticated:\n            token = Token.objects.get(user=request.user)\n        return render(\n            request, \"login/profile.html\", {\"profile_user\": user, \"token\": token}\n        )\n\n\nclass GroupManagement(View, LoginRequiredMixin):\n    def get(self, request):\n        \"\"\"\n        Load and list the available groups by groupadmin. \n        :param request: A HTTP-request object sent by the Django framework.\n        :param user_id: An user id\n        :return: Profile renderer   \n        \"\"\"\n\n        membership = request.user.memberships\n        return render(\n            request, \"login/list_memberships.html\", {\"membership\": membership}\n        )\n\n\nclass GroupCreate(View, LoginRequiredMixin):\n    def get(self, request, group_id=None):\n        \"\"\"\n        Load the chosen action(create or edit) for a group.\n        :param request: A HTTP-request object sent by the Django framework.\n        :param user_id: An user id\n        :param user_id: An group id\n        :return: Profile renderer\n        \"\"\"\n\n        if group_id:\n            group = UserGroup.objects.get(id=group_id)\n            form = GroupForm(instance=group)\n            membership = get_object_or_404(\n                GroupMembership, group=group, user=request.user\n            )\n            if membership.level < ADMIN_PERM:\n                raise PermissionDenied\n        else:\n            form = GroupForm()\n        return render(request, \"login/group_create.html\", {\"form\": form})\n\n    def post(self, request, group_id=None):\n        \"\"\"\n        Performs selected action(save or delete) for a group. If a groupname already exists, then a error\n        will be output.\n        The selected users become members of this group. The groupadmin is already set.\n        :param request: A HTTP-request object sent by the Django framework.\n        :param user_id: An user id\n        :param user_id: An group id\n        :return: Profile renderer\n        \"\"\"\n        group = UserGroup.objects.get(id=group_id) if group_id else None\n        form = GroupForm(request.POST, instance=group)\n        if form.is_valid():\n            if group_id:\n                group = form.save()\n                membership = get_object_or_404(\n                    GroupMembership, group=group, user=request.user\n                )\n                if membership.level < ADMIN_PERM:\n                    raise PermissionDenied\n            else:\n                group = form.save()\n                membership = GroupMembership.objects.create(\n                    user=request.user, group=group, level=ADMIN_PERM\n                )\n                membership.save()\n            return redirect(\"/user/groups/{id}\".format(id=group.id), {\"group\": group})\n        else:\n            return render(request, \"login/group_create.html\", {\"form\": form})\n\n\nclass GroupView(View, LoginRequiredMixin):\n    def get(self, request, group_id):\n        \"\"\"\n        Load the chosen action(create or edit) for a group.\n        :param request: A HTTP-request object sent by the Django framework.\n        :param user_id: An user id\n        :param user_id: An group id\n        :return: Profile renderer\n        \"\"\"\n        group = get_object_or_404(UserGroup, pk=group_id)\n        return render(\n            request,\n            \"login/group.html\",\n            {\"group\": group},\n        )\n\n\nclass GroupEdit(View, LoginRequiredMixin):\n    def get(self, request, group_id):\n        \"\"\"\n        Load the chosen action(create or edit) for a group. \n        :param request: A HTTP-request object sent by the Django framework.\n        :param user_id: An user id\n        :param user_id: An group id\n        :return: Profile renderer   \n        \"\"\"\n        group = get_object_or_404(UserGroup, pk=group_id)\n        is_admin = False\n        membership = GroupMembership.objects.filter(\n            group=group, user=request.user\n        ).first()\n        if membership:\n            is_admin = membership.level >= ADMIN_PERM\n        return render(\n            request,\n            \"login/change_form.html\",\n            {\"group\": group, \"choices\": GroupMembership.choices, \"is_admin\": is_admin},\n        )\n\n    def post(self, request, group_id):\n        \"\"\"\n        Performs selected action(save or delete) for a group. If a groupname already exists, then a error \n        will be output. \n        The selected users become members of this group. The groupadmin is already set.\n        :param request: A HTTP-request object sent by the Django framework.\n        :param user_id: An user id\n        :param user_id: An group id\n        :return: Profile renderer   \n        \"\"\"\n        mode = request.POST[\"mode\"]\n        group = get_object_or_404(UserGroup, id=group_id)\n        membership = get_object_or_404(GroupMembership, group=group, user=request.user)\n\n        errors = {}\n        if mode == \"add_user\":\n            if membership.level < models.WRITE_PERM:\n                raise PermissionDenied\n            try:\n                user = OepUser.objects.get(name=request.POST[\"name\"])\n                membership, _ = GroupMembership.objects.get_or_create(\n                    group=group, user=user\n                )\n                membership.save()\n            except OepUser.DoesNotExist:\n                errors[\"name\"] = \"User does not exist\"\n        elif mode == \"remove_user\":\n            if membership.level < models.DELETE_PERM:\n                raise PermissionDenied\n            user = OepUser.objects.get(id=request.POST[\"user_id\"])\n            membership = GroupMembership.objects.get(group=group, user=user)\n            if membership.level >= ADMIN_PERM:\n                admins = GroupMembership.objects.filter(group=group).exclude(user=user)\n                if not admins:\n                    errors[\"name\"] = \"A group needs at least one admin\"\n                else:\n                    membership.delete()\n            else:\n                membership.delete()\n        elif mode == \"alter_user\":\n            if membership.level < models.ADMIN_PERM:\n                raise PermissionDenied\n            user = OepUser.objects.get(id=request.POST[\"user_id\"])\n            if user == request.user:\n                errors[\"name\"] = \"You can not change your own permissions\"\n            else:\n                membership = GroupMembership.objects.get(group=group, user=user)\n                membership.level = request.POST[\"level\"]\n                membership.save()\n        elif mode == \"delete_group\":\n            if membership.level < models.ADMIN_PERM:\n                raise PermissionDenied\n            group.delete()\n            return redirect(\"/user/groups\")\n        else:\n            raise PermissionDenied\n        return render(\n            request,\n            \"login/change_form.html\",\n            {\n                \"group\": group,\n                \"choices\": GroupMembership.choices,\n                \"errors\": errors,\n                \"is_admin\": True,\n            },\n        )\n\n    def __add_user(self, request, group):\n        user = OepUser.objects.filter(id=request.POST[\"user_id\"]).first()\n        g = user.groups.add(group)\n        g.save()\n        return self.get(request)\n\n\nclass ProfileUpdateView(UpdateView, LoginRequiredMixin):\n    \"\"\"\n    Autogenerate a update form for users.\n    \"\"\"\n\n    model = OepUser\n    fields = [\"name\", \"affiliation\", \"email\"]\n    template_name_suffix = \"_update_form\"\n\n\nclass EditUserView(View):\n    def get(self, request, user_id):\n        if not request.user.id == int(user_id):\n            raise PermissionDenied\n        form = EditUserForm(instance=request.user)\n        return render(request, \"login/oepuser_edit_form.html\", {\"form\": form})\n\n    def post(self, request, user_id):\n        if not request.user.id == int(user_id):\n            raise PermissionDenied\n        form = EditUserForm(request.POST, instance=request.user)\n        if form.is_valid():\n            form.save()\n            return redirect(\"/user/profile/{id}\".format(id=request.user.id))\n        else:\n            return render(request, \"login/oepuser_edit_form.html\", {\"form\": form})\n\n\nclass CreateUserView(View):\n    def get(self, request):\n        form = CreateUserForm()\n        return render(request, \"login/oepuser_create_form.html\", {\"form\": form})\n\n    def post(self, request):\n        form = CreateUserForm(request.POST)\n        if form.is_valid():\n            user = form.save()\n            return redirect(\"activate\")\n        else:\n            return render(request, \"login/oepuser_create_form.html\", {\"form\": form})\n\n\nclass DetachView(LoginRequiredMixin, View):\n    def get(self, request):\n        if request.user.is_native:\n            raise PermissionDenied\n        form = DetachForm(request.user)\n        return render(request, \"login/detach.html\", {\"form\": form})\n\n    def post(self, request):\n        if request.user.is_native:\n            raise PermissionDenied\n        form = DetachForm(request.user, request.POST)\n        if form.is_valid():\n            form.save()\n            return redirect(\"/\")\n        else:\n            print(form.errors)\n            return render(request, \"login/detach.html\", {\"form\": form})\n\n\nclass OEPPasswordChangeView(PasswordChangeView):\n    template_name = \"login/generic_form.html\"\n    success_url = \"/\"\n\n\nclass ActivationNoteView(FormView):\n    template_name = \"login/activate.html\"\n    form_class = ChangeEmailForm\n    success_url = \"user/activate\"\n\n    def form_valid(self, form):\n        if self.request.user.is_anonymous or self.request.user.is_mail_verified:\n            raise PermissionDenied\n        form.save(self.request.user)\n        return super(ActivationNoteView, self).form_valid(form)\n\n\ndef activate(request, token):\n    token_obj = models.ActivationToken.objects.filter(value=token).first()\n    if not token_obj:\n        form = ChangeEmailForm()\n        form._errors = {\n            forms.forms.NON_FIELD_ERRORS: form.error_class(\n                [\"Your token was invalid or expired\"]\n            )\n        }\n        return render(request, \"login/activate.html\", {\"form\": form})\n    else:\n        token_obj.user.is_mail_verified = True\n        token_obj.user.save()\n        token_obj.delete()\n    return redirect(\"/user/profile/{id}\".format(id=token_obj.user.id))\n", "path": "login/views.py"}]}