• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

DemocracyClub / aggregator-api / 26192a4c-09ee-45f2-9fd7-d44d0520c829

04 Sep 2024 12:54PM UTC coverage: 76.041%. Remained the same
26192a4c-09ee-45f2-9fd7-d44d0520c829

push

circleci

chris48s
ensure setuptools is in frontend layer

1187 of 1561 relevant lines covered (76.04%)

0.76 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

52.63
/frontend/apps/api_users/views.py
1
# Create your views here.
2
from django.contrib import messages
1✔
3
from django.contrib.auth import get_user_model, login
1✔
4
from django.contrib.auth.mixins import LoginRequiredMixin
1✔
5
from django.contrib.messages.views import SuccessMessageMixin
1✔
6
from django.http.response import HttpResponseRedirect
1✔
7
from django.shortcuts import redirect
1✔
8
from django.template.loader import render_to_string
1✔
9
from django.urls import reverse
1✔
10
from django.views.generic import FormView
1✔
11
from django.views.generic.base import TemplateView
1✔
12
from django.views.generic.detail import DetailView
1✔
13
from django.views.generic.edit import DeleteView, UpdateView
1✔
14
from sesame.utils import get_query_string, get_user
1✔
15

16
from api_users.forms import APIKeyForm, LoginForm, UserProfileForm
1✔
17
from api_users.utils import get_domain, send_new_key_notification
1✔
18

19
User = get_user_model()
1✔
20

21
__all__ = ["LoginView"]
1✔
22

23

24
class LoginView(FormView):
1✔
25
    form_class = LoginForm
1✔
26
    template_name = "users/login.html"
1✔
27

28
    def form_valid(self, form):
1✔
29
        """
30
        Create or retrieve a user trigger the send login email
31
        """
32
        user, created = User.objects.get_or_create(
×
33
            email=form.cleaned_data["email"]
34
        )
35
        if created:
×
36
            user.set_unusable_password()
×
37
            user.save()
×
38

39
        self.send_login_url(user=user)
×
40
        messages.success(
×
41
            self.request,
42
            "Thank you, please check your email for your magic link to log in to your account.",
43
            fail_silently=True,
44
        )
45
        return HttpResponseRedirect(self.get_success_url())
×
46

47
    def send_login_url(self, user):
1✔
48
        """
49
        Send an email to the user with a link to authenticate and log in
50
        """
51
        querystring = get_query_string(user=user)
×
52
        domain = get_domain(request=self.request)
×
53
        path = reverse("api_users:authenticate")
×
54
        url = f"{self.request.scheme}://{domain}{path}{querystring}"
×
55
        subject = "Your magic link to log in to the Democracy Club API"
×
56
        txt = render_to_string(
×
57
            template_name="users/email/login_message.txt",
58
            context={
59
                "authenticate_url": url,
60
                "subject": subject,
61
            },
62
        )
63
        return user.email_user(subject=subject, message=txt)
×
64

65
    def get_success_url(self):
1✔
66
        """
67
        Redirect to same page where success message will be displayed
68
        """
69
        return reverse("api_users:login")
×
70

71

72
class AuthenticateView(TemplateView):
1✔
73
    template_name = "users/authenticate.html"
1✔
74

75
    def get(self, request, *args, **kwargs):
1✔
76
        """
77
        Attempts to get user from the request, log them in, and redirect them to
78
        their profile page. Renders an error message if django-sesame fails to
79
        get a user from the request.
80
        """
81
        user = get_user(request)
×
82
        if not user:
×
83
            return super().get(request, *args, **kwargs)
×
84

85
        login(request, user)
×
86
        if not user.name:
×
87
            return redirect("api_users:add_profile_details")
×
88
        return redirect("api_users:profile")
×
89

90

91
class UpdateProfileDetailsView(LoginRequiredMixin, UpdateView):
1✔
92
    form_class = UserProfileForm
1✔
93
    template_name = "users/update_profile.html"
1✔
94

95
    def get_object(self, queryset=None):
1✔
96
        return self.request.user
×
97

98
    def get_success_url(self):
1✔
99
        return reverse("api_users:profile")
×
100

101

102
class ProfileView(LoginRequiredMixin, FormView):
1✔
103
    template_name = "users/profile.html"
1✔
104
    form_class = APIKeyForm
1✔
105
    redirect_field_name = None
1✔
106

107
    def get_form_kwargs(self):
1✔
108
        kwargs = super().get_form_kwargs()
×
109
        kwargs["user"] = self.request.user
×
110
        return kwargs
×
111

112
    def get_context_data(self, **kwargs):
1✔
113
        context = super().get_context_data(**kwargs)
×
114
        context["api_keys"] = self.request.user.api_keys.all()
×
115
        return context
×
116

117
    def form_valid(self, form):
1✔
118
        """
119
        Build a APIKey via the form, attach the user from the request and save.
120
        """
121
        self.object = form.save()
×
122
        messages.success(
×
123
            self.request, f"{self.object.name} API key was created"
124
        )
125
        send_new_key_notification(self.request, self.object)
×
126

127
        return super().form_valid(form=form)
×
128

129
    def get_success_url(self):
1✔
130
        return reverse("api_users:profile")
×
131

132

133
class DeleteAPIKeyView(LoginRequiredMixin, SuccessMessageMixin, DeleteView):
1✔
134
    template_name = "users/delete_key.html"
1✔
135
    context_object_name = "key"
1✔
136

137
    def delete(self, request, *args, **kwargs):
1✔
138
        response = super().delete(request, *args, **kwargs)
×
139
        messages.success(request, f"{self.object.name} API key was deleted")
×
140
        return response
×
141

142
    def get_queryset(self):
1✔
143
        return self.request.user.api_keys.all()
×
144

145
    def get_success_url(self):
1✔
146
        return reverse("api_users:profile")
×
147

148

149
class RefreshAPIKeyView(LoginRequiredMixin, DetailView):
1✔
150
    template_name = "users/refresh_key.html"
1✔
151
    context_object_name = "key"
1✔
152

153
    def get_queryset(self):
1✔
154
        return self.request.user.api_keys.all()
×
155

156
    def post(self, request, *args, **kwargs):
1✔
157
        self.object = self.get_object()
×
158
        self.object.refresh_key()
×
159
        messages.success(
×
160
            request,
161
            f"{self.object.name} API key was refreshed",
162
            extra_tags="refreshed",
163
        )
164
        return redirect("api_users:profile")
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc