Compare commits
	
		
			4 commits
		
	
	
		
			37f3ed2506
			...
			a65b1574db
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| a65b1574db | |||
| 9731d4e793 | |||
| f9ea88cd24 | |||
| 4b7e311c62 | 
					 19 changed files with 295 additions and 93 deletions
				
			
		|  | @ -1,6 +1,9 @@ | ||||||
| Changelog | Changelog | ||||||
| ========= | ========= | ||||||
| 
 | 
 | ||||||
|  | * :feature:`-` add REST API to retrieve and set user information as admin | ||||||
|  | * :feature:`-` add support model for offline account reset codes in new help | ||||||
|  |   app | ||||||
| * :support:`-` remove unused PowerDNS support tables from domains app | * :support:`-` remove unused PowerDNS support tables from domains app | ||||||
| * :feature:`-` add impersonation support for superusers | * :feature:`-` add impersonation support for superusers | ||||||
| * :support:`-` remove django-braces dependency | * :support:`-` remove django-braces dependency | ||||||
|  |  | ||||||
|  | @ -7,19 +7,9 @@ from unittest.mock import patch | ||||||
| from django.test import TestCase | from django.test import TestCase | ||||||
| from django.contrib.auth import get_user_model | from django.contrib.auth import get_user_model | ||||||
| 
 | 
 | ||||||
| from domains.models import ( | from domains.models import HostingDomain, MailDomain | ||||||
|     DNSComment, |  | ||||||
|     DNSCryptoKey, |  | ||||||
|     DNSDomain, |  | ||||||
|     DNSDomainMetadata, |  | ||||||
|     DNSRecord, |  | ||||||
|     DNSSupermaster, |  | ||||||
|     DNSTSIGKey, |  | ||||||
|     HostingDomain, |  | ||||||
|     MailDomain, |  | ||||||
| ) |  | ||||||
| from hostingpackages.models import CustomerHostingPackage, HostingPackageTemplate |  | ||||||
| 
 | 
 | ||||||
|  | from hostingpackages.models import CustomerHostingPackage, HostingPackageTemplate | ||||||
| 
 | 
 | ||||||
| User = get_user_model() | User = get_user_model() | ||||||
| 
 | 
 | ||||||
|  | @ -77,49 +67,3 @@ class HostingDomainTest(TestCase): | ||||||
|     def test___str__(self): |     def test___str__(self): | ||||||
|         hostingdomain = HostingDomain(domain="test") |         hostingdomain = HostingDomain(domain="test") | ||||||
|         self.assertEqual(str(hostingdomain), "test") |         self.assertEqual(str(hostingdomain), "test") | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class DNSDomainTest(TestCase): |  | ||||||
|     def test___str__(self): |  | ||||||
|         dnsdomain = DNSDomain(domain="test") |  | ||||||
|         self.assertEqual(str(dnsdomain), "test") |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class DNSRecordTest(TestCase): |  | ||||||
|     def test___str__(self): |  | ||||||
|         dnsrecord = DNSRecord(name="localhost", recordtype="A", content="127.0.0.1") |  | ||||||
|         self.assertEqual(str(dnsrecord), "localhost IN A 127.0.0.1") |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class DNSSupermasterTest(TestCase): |  | ||||||
|     def test___str__(self): |  | ||||||
|         dnssupermaster = DNSSupermaster(ip="127.0.0.1", nameserver="dns.example.org") |  | ||||||
|         self.assertEqual(str(dnssupermaster), "127.0.0.1 dns.example.org") |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class DNSCommentTest(TestCase): |  | ||||||
|     def test___str__(self): |  | ||||||
|         dnscomment = DNSComment(name="localhost", commenttype="A", comment="good stuff") |  | ||||||
|         self.assertEqual(str(dnscomment), "localhost IN A: good stuff") |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class DNSDomainMetadataTest(TestCase): |  | ||||||
|     def test___str__(self): |  | ||||||
|         dnsdomain = DNSDomain(domain="test") |  | ||||||
|         dnsdomainmetadata = DNSDomainMetadata( |  | ||||||
|             domain=dnsdomain, kind="SOA-EDIT", content="INCEPTION" |  | ||||||
|         ) |  | ||||||
|         self.assertEqual(str(dnsdomainmetadata), "test SOA-EDIT INCEPTION") |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class DNSCryptoKeyTest(TestCase): |  | ||||||
|     def test___str__(self): |  | ||||||
|         dnsdomain = DNSDomain(domain="test") |  | ||||||
|         dnscryptokey = DNSCryptoKey(domain=dnsdomain, content="testvalue") |  | ||||||
|         self.assertEqual(str(dnscryptokey), "test testvalue") |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class DNSTSIGKeyTest(TestCase): |  | ||||||
|     def test___str__(self): |  | ||||||
|         dnstsigkey = DNSTSIGKey(name="testkey", algorithm="hmac-md5", secret="dummykey") |  | ||||||
|         self.assertEqual(str(dnstsigkey), "testkey hmac-md5 XXXX") |  | ||||||
|  |  | ||||||
|  | @ -207,6 +207,8 @@ DJANGO_APPS = ( | ||||||
|     "django.contrib.flatpages", |     "django.contrib.flatpages", | ||||||
|     "crispy_forms", |     "crispy_forms", | ||||||
|     "impersonate", |     "impersonate", | ||||||
|  |     "rest_framework", | ||||||
|  |     "rest_framework.authtoken", | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| ALLAUTH_APPS = ( | ALLAUTH_APPS = ( | ||||||
|  | @ -232,6 +234,7 @@ LOCAL_APPS = ( | ||||||
|     "userdbs", |     "userdbs", | ||||||
|     "hostingpackages", |     "hostingpackages", | ||||||
|     "websites", |     "websites", | ||||||
|  |     "help", | ||||||
|     "contact_form", |     "contact_form", | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | @ -263,6 +266,17 @@ CRISPY_TEMPLATE_PACK = "bootstrap3" | ||||||
| # ######### END CRISPY_FORMS CONFIGURATION | # ######### END CRISPY_FORMS CONFIGURATION | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | # ######### REST FRAMEWORK CONFIGURATION | ||||||
|  | REST_FRAMEWORK = { | ||||||
|  |     "DEFAULT_AUTHENTICATION_CLASSES": [ | ||||||
|  |         "rest_framework.authentication.BasicAuthentication", | ||||||
|  |         "rest_framework.authentication.SessionAuthentication", | ||||||
|  |         "rest_framework.authentication.TokenAuthentication", | ||||||
|  |     ] | ||||||
|  | } | ||||||
|  | # ######### END REST FRAMEWORK CONFIGURATION | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| # ######### LOGGING CONFIGURATION | # ######### LOGGING CONFIGURATION | ||||||
| # See: https://docs.djangoproject.com/en/dev/ref/settings/#logging | # See: https://docs.djangoproject.com/en/dev/ref/settings/#logging | ||||||
| # A sample logging configuration. The only tangible logging | # A sample logging configuration. The only tangible logging | ||||||
|  | @ -404,23 +418,8 @@ if GVA_ENVIRONMENT == "local": | ||||||
|         dict( |         dict( | ||||||
|             [ |             [ | ||||||
|                 (key, {"handlers": ["console"], "level": "DEBUG", "propagate": True}) |                 (key, {"handlers": ["console"], "level": "DEBUG", "propagate": True}) | ||||||
|                 for key in [ |                 for key in LOCAL_APPS | ||||||
|                 "dashboard", |             ], | ||||||
|                 "domains", |  | ||||||
|                 "fileservertasks", |  | ||||||
|                 "gvacommon", |  | ||||||
|                 "gvawebcore", |  | ||||||
|                 "hostingpackages", |  | ||||||
|                 "ldaptasks", |  | ||||||
|                 "managemails", |  | ||||||
|                 "mysqltasks", |  | ||||||
|                 "osusers", |  | ||||||
|                 "pgsqltasks", |  | ||||||
|                 "taskresults", |  | ||||||
|                 "userdbs", |  | ||||||
|                 "websites", |  | ||||||
|             ] |  | ||||||
|             ] |  | ||||||
|         ) |         ) | ||||||
|     ) |     ) | ||||||
| elif GVA_ENVIRONMENT == "test": | elif GVA_ENVIRONMENT == "test": | ||||||
|  | @ -439,22 +438,7 @@ elif GVA_ENVIRONMENT == "test": | ||||||
|         dict( |         dict( | ||||||
|             [ |             [ | ||||||
|                 (key, {"handlers": ["console"], "level": "ERROR", "propagate": True}) |                 (key, {"handlers": ["console"], "level": "ERROR", "propagate": True}) | ||||||
|                 for key in [ |                 for key in LOCAL_APPS | ||||||
|                 "dashboard", |  | ||||||
|                 "domains", |  | ||||||
|                 "fileservertasks", |  | ||||||
|                 "gvacommon", |  | ||||||
|                 "gvawebcore", |  | ||||||
|                 "hostingpackages", |  | ||||||
|                 "ldaptasks", |  | ||||||
|                 "managemails", |  | ||||||
|                 "mysqltasks", |  | ||||||
|                 "osusers", |  | ||||||
|                 "pgsqltasks", |  | ||||||
|                 "taskresults", |  | ||||||
|                 "userdbs", |  | ||||||
|                 "websites", |  | ||||||
|             ] |  | ||||||
|             ] |             ] | ||||||
|         ) |         ) | ||||||
|     ) |     ) | ||||||
|  |  | ||||||
|  | @ -6,11 +6,20 @@ from django.contrib import admin | ||||||
| from django.contrib.flatpages import views | from django.contrib.flatpages import views | ||||||
| from django.contrib.staticfiles.urls import staticfiles_urlpatterns | from django.contrib.staticfiles.urls import staticfiles_urlpatterns | ||||||
| from django.urls import path, re_path | from django.urls import path, re_path | ||||||
|  | from rest_framework import routers | ||||||
|  | 
 | ||||||
|  | from help import views as help_views | ||||||
| 
 | 
 | ||||||
| admin.autodiscover() | admin.autodiscover() | ||||||
| 
 | 
 | ||||||
|  | router = routers.DefaultRouter() | ||||||
|  | router.register(r"users", help_views.UserViewSet) | ||||||
|  | router.register(r"help-users", help_views.HelpUserViewSet) | ||||||
|  | 
 | ||||||
| urlpatterns = [ | urlpatterns = [ | ||||||
|     re_path(r"", include("dashboard.urls")), |     re_path(r"", include("dashboard.urls")), | ||||||
|  |     path("api/", include(router.urls)), | ||||||
|  |     path("api-auth/", include("rest_framework.urls", namespace="rest_framework")), | ||||||
|     re_path(r"^admin/", admin.site.urls), |     re_path(r"^admin/", admin.site.urls), | ||||||
|     re_path(r"^impersonate/", include("impersonate.urls")), |     re_path(r"^impersonate/", include("impersonate.urls")), | ||||||
|     re_path(r"^accounts/", include("allauth.urls")), |     re_path(r"^accounts/", include("allauth.urls")), | ||||||
|  |  | ||||||
							
								
								
									
										0
									
								
								gnuviechadmin/help/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								gnuviechadmin/help/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
								
								
									
										22
									
								
								gnuviechadmin/help/admin.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								gnuviechadmin/help/admin.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,22 @@ | ||||||
|  | from django.contrib import admin | ||||||
|  | from django.contrib.auth import get_user_model | ||||||
|  | from django.contrib.auth.admin import UserAdmin as BaseUserAdmin | ||||||
|  | from django.utils.translation import ugettext_lazy as _ | ||||||
|  | 
 | ||||||
|  | from help.models import HelpUser | ||||||
|  | 
 | ||||||
|  | User = get_user_model() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class HelpUserInline(admin.StackedInline): | ||||||
|  |     model = HelpUser | ||||||
|  |     can_delete = False | ||||||
|  |     readonly_fields = ("offline_account_code",) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class UserAdmin(BaseUserAdmin): | ||||||
|  |     inlines = (HelpUserInline,) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | admin.site.unregister(User) | ||||||
|  | admin.site.register(User, UserAdmin) | ||||||
							
								
								
									
										8
									
								
								gnuviechadmin/help/apps.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								gnuviechadmin/help/apps.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,8 @@ | ||||||
|  | from django.apps import AppConfig | ||||||
|  | from django.utils.translation import gettext_lazy as _ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class HelpConfig(AppConfig): | ||||||
|  |     default_auto_field = "django.db.models.BigAutoField" | ||||||
|  |     name = "help" | ||||||
|  |     verbose_name = _("User self help") | ||||||
							
								
								
									
										0
									
								
								gnuviechadmin/help/management/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								gnuviechadmin/help/management/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								gnuviechadmin/help/management/commands/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								gnuviechadmin/help/management/commands/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
								
								
									
										17
									
								
								gnuviechadmin/help/management/commands/populate.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								gnuviechadmin/help/management/commands/populate.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,17 @@ | ||||||
|  | from django.contrib.auth import get_user_model | ||||||
|  | from django.core.management import BaseCommand | ||||||
|  | 
 | ||||||
|  | from help.models import HelpUser | ||||||
|  | 
 | ||||||
|  | User = get_user_model() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class Command(BaseCommand): | ||||||
|  |     help = "Populate help user information for existing users" | ||||||
|  | 
 | ||||||
|  |     def handle(self, *args, **options): | ||||||
|  |         for user in User.objects.filter(helpuser=None): | ||||||
|  |             help_user = HelpUser.objects.create(user_id=user.id, email_address=user.email) | ||||||
|  |             help_user.generate_offline_account_code() | ||||||
|  |             help_user.save() | ||||||
|  |             self.stdout.write(f"created offline account code {help_user.offline_account_code} for {user}.") | ||||||
							
								
								
									
										29
									
								
								gnuviechadmin/help/management/commands/reset_offline_code.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								gnuviechadmin/help/management/commands/reset_offline_code.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,29 @@ | ||||||
|  | from django.contrib.auth import get_user_model | ||||||
|  | from django.core.management import BaseCommand, CommandError | ||||||
|  | 
 | ||||||
|  | from help.models import HelpUser | ||||||
|  | 
 | ||||||
|  | User = get_user_model() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class Command(BaseCommand): | ||||||
|  |     help = "Reset offline account reset code for existing users" | ||||||
|  | 
 | ||||||
|  |     def add_arguments(self, parser): | ||||||
|  |         parser.add_argument("users", nargs='+', type=str) | ||||||
|  | 
 | ||||||
|  |     def handle(self, *args, **options): | ||||||
|  |         for name in options["users"]: | ||||||
|  |             try: | ||||||
|  |                 user = User.objects.get(username=name) | ||||||
|  |             except User.DoesNotExist: | ||||||
|  |                 raise CommandError(f'User {name} does not exist') | ||||||
|  | 
 | ||||||
|  |             help_user = user.helpuser | ||||||
|  |             if help_user is None: | ||||||
|  |                 help_user = HelpUser.objects.create(email_address=user.email) | ||||||
|  | 
 | ||||||
|  |             help_user.generate_offline_account_code() | ||||||
|  |             help_user.save() | ||||||
|  | 
 | ||||||
|  |             self.stdout.write(f"generated new offline account reset code {help_user.offline_account_code} for {name}") | ||||||
|  | @ -0,0 +1,55 @@ | ||||||
|  | # Generated by Django 3.2.18 on 2023-04-16 09:32 | ||||||
|  | 
 | ||||||
|  | import django.db.models.deletion | ||||||
|  | from django.conf import settings | ||||||
|  | from django.db import migrations, models | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class Migration(migrations.Migration): | ||||||
|  |     initial = True | ||||||
|  | 
 | ||||||
|  |     dependencies = [ | ||||||
|  |         migrations.swappable_dependency(settings.AUTH_USER_MODEL), | ||||||
|  |     ] | ||||||
|  | 
 | ||||||
|  |     operations = [ | ||||||
|  |         migrations.CreateModel( | ||||||
|  |             name="HelpUser", | ||||||
|  |             fields=[ | ||||||
|  |                 ( | ||||||
|  |                     "id", | ||||||
|  |                     models.BigAutoField( | ||||||
|  |                         auto_created=True, | ||||||
|  |                         primary_key=True, | ||||||
|  |                         serialize=False, | ||||||
|  |                         verbose_name="ID", | ||||||
|  |                     ), | ||||||
|  |                 ), | ||||||
|  |                 ( | ||||||
|  |                     "email_address", | ||||||
|  |                     models.EmailField( | ||||||
|  |                         help_text="Contact email address", max_length=254 | ||||||
|  |                     ), | ||||||
|  |                 ), | ||||||
|  |                 ( | ||||||
|  |                     "postal_address", | ||||||
|  |                     models.TextField(blank=True, help_text="Contact postal address"), | ||||||
|  |                 ), | ||||||
|  |                 ( | ||||||
|  |                     "offline_account_code", | ||||||
|  |                     models.CharField( | ||||||
|  |                         default="", | ||||||
|  |                         help_text="Offline account reset code", | ||||||
|  |                         max_length=36, | ||||||
|  |                     ), | ||||||
|  |                 ), | ||||||
|  |                 ( | ||||||
|  |                     "user", | ||||||
|  |                     models.OneToOneField( | ||||||
|  |                         on_delete=django.db.models.deletion.CASCADE, | ||||||
|  |                         to=settings.AUTH_USER_MODEL, | ||||||
|  |                     ), | ||||||
|  |                 ), | ||||||
|  |             ], | ||||||
|  |         ), | ||||||
|  |     ] | ||||||
							
								
								
									
										0
									
								
								gnuviechadmin/help/migrations/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								gnuviechadmin/help/migrations/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
								
								
									
										17
									
								
								gnuviechadmin/help/models.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								gnuviechadmin/help/models.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,17 @@ | ||||||
|  | import uuid | ||||||
|  | 
 | ||||||
|  | from django.conf import settings | ||||||
|  | from django.db import models | ||||||
|  | from django.utils.translation import ugettext_lazy as _ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class HelpUser(models.Model): | ||||||
|  |     user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) | ||||||
|  |     email_address = models.EmailField(help_text=_("Contact email address")) | ||||||
|  |     postal_address = models.TextField(help_text=_("Contact postal address"), blank=True) | ||||||
|  |     offline_account_code = models.CharField( | ||||||
|  |         help_text=_("Offline account reset code"), max_length=36, default="" | ||||||
|  |     ) | ||||||
|  | 
 | ||||||
|  |     def generate_offline_account_code(self): | ||||||
|  |         self.offline_account_code = str(uuid.uuid4()) | ||||||
							
								
								
									
										30
									
								
								gnuviechadmin/help/serializers.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								gnuviechadmin/help/serializers.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,30 @@ | ||||||
|  | """ | ||||||
|  | Serializers for the REST API | ||||||
|  | """ | ||||||
|  | 
 | ||||||
|  | from django.contrib.auth import get_user_model | ||||||
|  | from rest_framework import serializers | ||||||
|  | 
 | ||||||
|  | from help.models import HelpUser | ||||||
|  | 
 | ||||||
|  | User = get_user_model() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class UserSerializer(serializers.HyperlinkedModelSerializer): | ||||||
|  |     class Meta: | ||||||
|  |         model = User | ||||||
|  |         fields = ["url", "username", "helpuser"] | ||||||
|  |         read_only_fields = ["username", "helpuser"] | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class HelpUserSerializer(serializers.HyperlinkedModelSerializer): | ||||||
|  |     class Meta: | ||||||
|  |         model = HelpUser | ||||||
|  |         fields = [ | ||||||
|  |             "url", | ||||||
|  |             "user", | ||||||
|  |             "email_address", | ||||||
|  |             "postal_address", | ||||||
|  |             "offline_account_code", | ||||||
|  |         ] | ||||||
|  |         read_only_fields = ["user", "offline_account_code"] | ||||||
							
								
								
									
										3
									
								
								gnuviechadmin/help/tests.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								gnuviechadmin/help/tests.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,3 @@ | ||||||
|  | from django.test import TestCase | ||||||
|  | 
 | ||||||
|  | # Create your tests here. | ||||||
							
								
								
									
										29
									
								
								gnuviechadmin/help/views.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								gnuviechadmin/help/views.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,29 @@ | ||||||
|  | from django.contrib.auth import get_user_model | ||||||
|  | from rest_framework import permissions, viewsets | ||||||
|  | 
 | ||||||
|  | from help.models import HelpUser | ||||||
|  | from help.serializers import HelpUserSerializer, UserSerializer | ||||||
|  | 
 | ||||||
|  | User = get_user_model() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class UserViewSet(viewsets.ReadOnlyModelViewSet): | ||||||
|  |     """ | ||||||
|  |     API endpoint that allows users to be viewed or edited. | ||||||
|  | 
 | ||||||
|  |     """ | ||||||
|  | 
 | ||||||
|  |     queryset = User.objects.all().order_by("-username") | ||||||
|  |     serializer_class = UserSerializer | ||||||
|  |     permission_classes = [permissions.IsAdminUser] | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class HelpUserViewSet(viewsets.ModelViewSet): | ||||||
|  |     """ | ||||||
|  |     API endpoint that allows user help profile to be viewed or edited. | ||||||
|  | 
 | ||||||
|  |     """ | ||||||
|  | 
 | ||||||
|  |     queryset = HelpUser.objects.all().order_by("-user__username") | ||||||
|  |     serializer_class = HelpUserSerializer | ||||||
|  |     permission_classes = [permissions.IsAdminUser] | ||||||
							
								
								
									
										51
									
								
								poetry.lock
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										51
									
								
								poetry.lock
									
										
									
										generated
									
									
									
								
							|  | @ -666,6 +666,21 @@ files = [ | ||||||
| django = ">=3.2.4" | django = ">=3.2.4" | ||||||
| sqlparse = ">=0.2" | sqlparse = ">=0.2" | ||||||
| 
 | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "django-filter" | ||||||
|  | version = "23.1" | ||||||
|  | description = "Django-filter is a reusable Django application for allowing users to filter querysets dynamically." | ||||||
|  | category = "main" | ||||||
|  | optional = false | ||||||
|  | python-versions = ">=3.7" | ||||||
|  | files = [ | ||||||
|  |     {file = "django-filter-23.1.tar.gz", hash = "sha256:dee5dcf2cea4d7f767e271b6d01f767fce7500676d5e5dc58dac8154000b87df"}, | ||||||
|  |     {file = "django_filter-23.1-py3-none-any.whl", hash = "sha256:e3c52ad83c32fb5882125105efb5fea2a1d6a85e7dc64b04ef52edbf14451b6c"}, | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [package.dependencies] | ||||||
|  | Django = ">=3.2" | ||||||
|  | 
 | ||||||
| [[package]] | [[package]] | ||||||
| name = "django-impersonate" | name = "django-impersonate" | ||||||
| version = "1.9.1" | version = "1.9.1" | ||||||
|  | @ -692,6 +707,22 @@ files = [ | ||||||
| [package.dependencies] | [package.dependencies] | ||||||
| Django = ">=3.2" | Django = ">=3.2" | ||||||
| 
 | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "djangorestframework" | ||||||
|  | version = "3.14.0" | ||||||
|  | description = "Web APIs for Django, made easy." | ||||||
|  | category = "main" | ||||||
|  | optional = false | ||||||
|  | python-versions = ">=3.6" | ||||||
|  | files = [ | ||||||
|  |     {file = "djangorestframework-3.14.0-py3-none-any.whl", hash = "sha256:eb63f58c9f218e1a7d064d17a70751f528ed4e1d35547fdade9aaf4cd103fd08"}, | ||||||
|  |     {file = "djangorestframework-3.14.0.tar.gz", hash = "sha256:579a333e6256b09489cbe0a067e66abe55c6595d8926be6b99423786334350c8"}, | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [package.dependencies] | ||||||
|  | django = ">=3.0" | ||||||
|  | pytz = "*" | ||||||
|  | 
 | ||||||
| [[package]] | [[package]] | ||||||
| name = "docutils" | name = "docutils" | ||||||
| version = "0.19" | version = "0.19" | ||||||
|  | @ -850,6 +881,24 @@ sqs = ["boto3 (>=1.9.12)", "pycurl (>=7.44.1,<7.45.0)", "urllib3 (>=1.26.7)"] | ||||||
| yaml = ["PyYAML (>=3.10)"] | yaml = ["PyYAML (>=3.10)"] | ||||||
| zookeeper = ["kazoo (>=1.3.1)"] | zookeeper = ["kazoo (>=1.3.1)"] | ||||||
| 
 | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "markdown" | ||||||
|  | version = "3.4.3" | ||||||
|  | description = "Python implementation of John Gruber's Markdown." | ||||||
|  | category = "main" | ||||||
|  | optional = false | ||||||
|  | python-versions = ">=3.7" | ||||||
|  | files = [ | ||||||
|  |     {file = "Markdown-3.4.3-py3-none-any.whl", hash = "sha256:065fd4df22da73a625f14890dd77eb8040edcbd68794bcd35943be14490608b2"}, | ||||||
|  |     {file = "Markdown-3.4.3.tar.gz", hash = "sha256:8bf101198e004dc93e84a12a7395e31aac6a9c9942848ae1d99b9d72cf9b3520"}, | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [package.dependencies] | ||||||
|  | importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""} | ||||||
|  | 
 | ||||||
|  | [package.extras] | ||||||
|  | testing = ["coverage", "pyyaml"] | ||||||
|  | 
 | ||||||
| [[package]] | [[package]] | ||||||
| name = "markupsafe" | name = "markupsafe" | ||||||
| version = "2.1.2" | version = "2.1.2" | ||||||
|  | @ -1753,4 +1802,4 @@ testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more | ||||||
| [metadata] | [metadata] | ||||||
| lock-version = "2.0" | lock-version = "2.0" | ||||||
| python-versions = "^3.7" | python-versions = "^3.7" | ||||||
| content-hash = "dd56e0233689448f08dfcae943871bf9d72c05ad7bfd326c69f9ecb33ea8a461" | content-hash = "12e95bb19c0dc9d4b1388423e1007628e37e5e13a217de01b27bb34b20d5ac34" | ||||||
|  |  | ||||||
|  | @ -20,6 +20,9 @@ passlib = "^1.7.4" | ||||||
| redis = "^4.5.1" | redis = "^4.5.1" | ||||||
| requests-oauthlib = "^1.3.1" | requests-oauthlib = "^1.3.1" | ||||||
| django-impersonate = "^1.9.1" | django-impersonate = "^1.9.1" | ||||||
|  | djangorestframework = "^3.14.0" | ||||||
|  | markdown = "^3.4.3" | ||||||
|  | django-filter = "^23.1" | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| [tool.poetry.group.dev.dependencies] | [tool.poetry.group.dev.dependencies] | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue