views.py 21 KB
Newer Older
1
# -*- mode: python; coding: utf-8 -*-
Maël Kervella's avatar
Maël Kervella committed
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
# Re2o est un logiciel d'administration développé initiallement au rezometz. Il
# se veut agnostique au réseau considéré, de manière à être installable en
# quelques clics.
#
# Copyright © 2018 Maël Kervella
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

22
"""Defines the views of the API
Maël Kervella's avatar
Maël Kervella committed
23

24 25 26
All views inherits the `rest_framework.views.APIview` to respect the
REST API requirements such as dealing with HTTP status code, format of
the response (JSON or other), the CSRF exempting, ...
Maël Kervella's avatar
Maël Kervella committed
27
"""
28

29
import datetime
30

31 32 33
from django.conf import settings
from rest_framework.authtoken.views import ObtainAuthToken
from rest_framework.authtoken.models import Token
Maël Kervella's avatar
Maël Kervella committed
34
from rest_framework.response import Response
35
from rest_framework import viewsets, generics, views
Maël Kervella's avatar
Maël Kervella committed
36

Maël Kervella's avatar
Maël Kervella committed
37 38 39 40 41
import cotisations.models as cotisations
import machines.models as machines
import preferences.models as preferences
import topologie.models as topologie
import users.models as users
42
from re2o.utils import all_active_interfaces, all_has_access
43

Maël Kervella's avatar
Maël Kervella committed
44
from . import serializers
45
from .pagination import PageSizedPagination
46
from .permissions import ACLPermission
47

Maël Kervella's avatar
Maël Kervella committed
48

49
# COTISATIONS
50 51 52


class FactureViewSet(viewsets.ReadOnlyModelViewSet):
53 54
    """Exposes list and details of `cotisations.models.Facture` objects.
    """
Maël Kervella's avatar
Maël Kervella committed
55 56
    queryset = cotisations.Facture.objects.all()
    serializer_class = serializers.FactureSerializer
57 58 59


class VenteViewSet(viewsets.ReadOnlyModelViewSet):
60 61
    """Exposes list and details of `cotisations.models.Vente` objects.
    """
Maël Kervella's avatar
Maël Kervella committed
62 63
    queryset = cotisations.Vente.objects.all()
    serializer_class = serializers.VenteSerializer
64 65 66


class ArticleViewSet(viewsets.ReadOnlyModelViewSet):
67 68
    """Exposes list and details of `cotisations.models.Article` objects.
    """
Maël Kervella's avatar
Maël Kervella committed
69 70
    queryset = cotisations.Article.objects.all()
    serializer_class = serializers.ArticleSerializer
71 72 73


class BanqueViewSet(viewsets.ReadOnlyModelViewSet):
74 75
    """Exposes list and details of `cotisations.models.Banque` objects.
    """
Maël Kervella's avatar
Maël Kervella committed
76 77
    queryset = cotisations.Banque.objects.all()
    serializer_class = serializers.BanqueSerializer
78 79 80


class PaiementViewSet(viewsets.ReadOnlyModelViewSet):
81 82
    """Exposes list and details of `cotisations.models.Paiement` objects.
    """
Maël Kervella's avatar
Maël Kervella committed
83 84
    queryset = cotisations.Paiement.objects.all()
    serializer_class = serializers.PaiementSerializer
85 86 87


class CotisationViewSet(viewsets.ReadOnlyModelViewSet):
88 89
    """Exposes list and details of `cotisations.models.Cotisation` objects.
    """
Maël Kervella's avatar
Maël Kervella committed
90 91
    queryset = cotisations.Cotisation.objects.all()
    serializer_class = serializers.CotisationSerializer
92 93


94
# MACHINES
95 96 97


class MachineViewSet(viewsets.ReadOnlyModelViewSet):
98 99
    """Exposes list and details of `machines.models.Machine` objects.
    """
Maël Kervella's avatar
Maël Kervella committed
100 101
    queryset = machines.Machine.objects.all()
    serializer_class = serializers.MachineSerializer
102 103 104


class MachineTypeViewSet(viewsets.ReadOnlyModelViewSet):
105 106
    """Exposes list and details of `machines.models.MachineType` objects.
    """
Maël Kervella's avatar
Maël Kervella committed
107 108
    queryset = machines.MachineType.objects.all()
    serializer_class = serializers.MachineTypeSerializer
109 110 111


class IpTypeViewSet(viewsets.ReadOnlyModelViewSet):
112 113
    """Exposes list and details of `machines.models.IpType` objects.
    """
Maël Kervella's avatar
Maël Kervella committed
114 115
    queryset = machines.IpType.objects.all()
    serializer_class = serializers.IpTypeSerializer
116 117 118


class VlanViewSet(viewsets.ReadOnlyModelViewSet):
119 120
    """Exposes list and details of `machines.models.Vlan` objects.
    """
Maël Kervella's avatar
Maël Kervella committed
121 122
    queryset = machines.Vlan.objects.all()
    serializer_class = serializers.VlanSerializer
123 124 125


class NasViewSet(viewsets.ReadOnlyModelViewSet):
126 127
    """Exposes list and details of `machines.models.Nas` objects.
    """
Maël Kervella's avatar
Maël Kervella committed
128 129
    queryset = machines.Nas.objects.all()
    serializer_class = serializers.NasSerializer
130 131 132


class SOAViewSet(viewsets.ReadOnlyModelViewSet):
133 134
    """Exposes list and details of `machines.models.SOA` objects.
    """
Maël Kervella's avatar
Maël Kervella committed
135 136
    queryset = machines.SOA.objects.all()
    serializer_class = serializers.SOASerializer
137 138 139


class ExtensionViewSet(viewsets.ReadOnlyModelViewSet):
140 141
    """Exposes list and details of `machines.models.Extension` objects.
    """
Maël Kervella's avatar
Maël Kervella committed
142 143
    queryset = machines.Extension.objects.all()
    serializer_class = serializers.ExtensionSerializer
144 145 146


class MxViewSet(viewsets.ReadOnlyModelViewSet):
147 148
    """Exposes list and details of `machines.models.Mx` objects.
    """
Maël Kervella's avatar
Maël Kervella committed
149 150
    queryset = machines.Mx.objects.all()
    serializer_class = serializers.MxSerializer
151 152 153


class NsViewSet(viewsets.ReadOnlyModelViewSet):
154 155
    """Exposes list and details of `machines.models.Ns` objects.
    """
Maël Kervella's avatar
Maël Kervella committed
156 157
    queryset = machines.Ns.objects.all()
    serializer_class = serializers.NsSerializer
158 159 160


class TxtViewSet(viewsets.ReadOnlyModelViewSet):
161 162
    """Exposes list and details of `machines.models.Txt` objects.
    """
Maël Kervella's avatar
Maël Kervella committed
163 164
    queryset = machines.Txt.objects.all()
    serializer_class = serializers.TxtSerializer
165 166 167 168 169 170

class DNameViewSet(viewsets.ReadOnlyModelViewSet):
    """Exposes list and details of `machines.models.DName` objects.
    """
    queryset = machines.DName.objects.all()
    serializer_class = serializers.DNameSerializer
171 172 173


class SrvViewSet(viewsets.ReadOnlyModelViewSet):
174 175
    """Exposes list and details of `machines.models.Srv` objects.
    """
Maël Kervella's avatar
Maël Kervella committed
176 177
    queryset = machines.Srv.objects.all()
    serializer_class = serializers.SrvSerializer
178 179


180 181 182 183 184 185 186
class SshFpViewSet(viewsets.ReadOnlyModelViewSet):
    """Exposes list and details of `machines.models.SshFp` objects.
    """
    queryset = machines.SshFp.objects.all()
    serializer_class = serializers.SshFpSerializer


187
class InterfaceViewSet(viewsets.ReadOnlyModelViewSet):
188 189
    """Exposes list and details of `machines.models.Interface` objects.
    """
Maël Kervella's avatar
Maël Kervella committed
190 191
    queryset = machines.Interface.objects.all()
    serializer_class = serializers.InterfaceSerializer
192 193 194


class Ipv6ListViewSet(viewsets.ReadOnlyModelViewSet):
195 196
    """Exposes list and details of `machines.models.Ipv6List` objects.
    """
Maël Kervella's avatar
Maël Kervella committed
197 198
    queryset = machines.Ipv6List.objects.all()
    serializer_class = serializers.Ipv6ListSerializer
199 200 201


class DomainViewSet(viewsets.ReadOnlyModelViewSet):
202 203
    """Exposes list and details of `machines.models.Domain` objects.
    """
Maël Kervella's avatar
Maël Kervella committed
204 205
    queryset = machines.Domain.objects.all()
    serializer_class = serializers.DomainSerializer
206 207 208


class IpListViewSet(viewsets.ReadOnlyModelViewSet):
209 210
    """Exposes list and details of `machines.models.IpList` objects.
    """
Maël Kervella's avatar
Maël Kervella committed
211 212
    queryset = machines.IpList.objects.all()
    serializer_class = serializers.IpListSerializer
213 214 215


class ServiceViewSet(viewsets.ReadOnlyModelViewSet):
216 217
    """Exposes list and details of `machines.models.Service` objects.
    """
Maël Kervella's avatar
Maël Kervella committed
218 219
    queryset = machines.Service.objects.all()
    serializer_class = serializers.ServiceSerializer
220 221


222
class ServiceLinkViewSet(viewsets.ReadOnlyModelViewSet):
223 224
    """Exposes list and details of `machines.models.Service_link` objects.
    """
Maël Kervella's avatar
Maël Kervella committed
225 226
    queryset = machines.Service_link.objects.all()
    serializer_class = serializers.ServiceLinkSerializer
227 228 229


class OuverturePortListViewSet(viewsets.ReadOnlyModelViewSet):
230 231 232
    """Exposes list and details of `machines.models.OuverturePortList`
    objects.
    """
Maël Kervella's avatar
Maël Kervella committed
233 234
    queryset = machines.OuverturePortList.objects.all()
    serializer_class = serializers.OuverturePortListSerializer
235 236 237


class OuverturePortViewSet(viewsets.ReadOnlyModelViewSet):
238 239
    """Exposes list and details of `machines.models.OuverturePort` objects.
    """
Maël Kervella's avatar
Maël Kervella committed
240 241
    queryset = machines.OuverturePort.objects.all()
    serializer_class = serializers.OuverturePortSerializer
242 243


244
# PREFERENCES
245 246
# Those views differ a bit because there is only one object
# to display, so we don't bother with the listing part
247

248
class OptionalUserView(generics.RetrieveAPIView):
249 250
    """Exposes details of `preferences.models.` settings.
    """
251 252 253 254 255 256 257 258 259
    permission_classes = (ACLPermission, )
    perms_map = {'GET' : [preferences.OptionalUser.can_view_all]}
    serializer_class = serializers.OptionalUserSerializer

    def get_object(self):
        return preferences.OptionalUser.objects.first()


class OptionalMachineView(generics.RetrieveAPIView):
260 261
    """Exposes details of `preferences.models.OptionalMachine` settings.
    """
262 263 264 265 266 267 268 269 270
    permission_classes = (ACLPermission, )
    perms_map = {'GET' : [preferences.OptionalMachine.can_view_all]}
    serializer_class = serializers.OptionalMachineSerializer

    def get_object(self):
        return preferences.OptionalMachine.objects.first()


class OptionalTopologieView(generics.RetrieveAPIView):
271 272
    """Exposes details of `preferences.models.OptionalTopologie` settings.
    """
273 274 275 276 277 278 279 280 281
    permission_classes = (ACLPermission, )
    perms_map = {'GET' : [preferences.OptionalTopologie.can_view_all]}
    serializer_class = serializers.OptionalTopologieSerializer

    def get_object(self):
        return preferences.OptionalTopologie.objects.first()


class GeneralOptionView(generics.RetrieveAPIView):
282 283
    """Exposes details of `preferences.models.GeneralOption` settings.
    """
284 285 286 287 288 289 290 291
    permission_classes = (ACLPermission, )
    perms_map = {'GET' : [preferences.GeneralOption.can_view_all]}
    serializer_class = serializers.GeneralOptionSerializer

    def get_object(self):
        return preferences.GeneralOption.objects.first()


292
class HomeServiceViewSet(viewsets.ReadOnlyModelViewSet):
293 294
    """Exposes list and details of `preferences.models.Service` objects.
    """
295
    queryset = preferences.Service.objects.all()
296
    serializer_class = serializers.HomeServiceSerializer
297 298 299


class AssoOptionView(generics.RetrieveAPIView):
300 301
    """Exposes details of `preferences.models.AssoOption` settings.
    """
302 303 304 305 306 307 308 309 310
    permission_classes = (ACLPermission, )
    perms_map = {'GET' : [preferences.AssoOption.can_view_all]}
    serializer_class = serializers.AssoOptionSerializer

    def get_object(self):
        return preferences.AssoOption.objects.first()


class HomeOptionView(generics.RetrieveAPIView):
311 312
    """Exposes details of `preferences.models.HomeOption` settings.
    """
313 314 315 316 317 318 319 320 321
    permission_classes = (ACLPermission, )
    perms_map = {'GET' : [preferences.HomeOption.can_view_all]}
    serializer_class = serializers.HomeOptionSerializer

    def get_object(self):
        return preferences.HomeOption.objects.first()


class MailMessageOptionView(generics.RetrieveAPIView):
322 323
    """Exposes details of `preferences.models.MailMessageOption` settings.
    """
324 325 326 327 328 329
    permission_classes = (ACLPermission, )
    perms_map = {'GET' : [preferences.MailMessageOption.can_view_all]}
    serializer_class = serializers.MailMessageOptionSerializer

    def get_object(self):
        return preferences.MailMessageOption.objects.first()
330 331


332
# TOPOLOGIE
333 334 335


class StackViewSet(viewsets.ReadOnlyModelViewSet):
336 337
    """Exposes list and details of `topologie.models.Stack` objects.
    """
Maël Kervella's avatar
Maël Kervella committed
338 339
    queryset = topologie.Stack.objects.all()
    serializer_class = serializers.StackSerializer
340 341 342


class AccessPointViewSet(viewsets.ReadOnlyModelViewSet):
343 344
    """Exposes list and details of `topologie.models.AccessPoint` objects.
    """
Maël Kervella's avatar
Maël Kervella committed
345 346
    queryset = topologie.AccessPoint.objects.all()
    serializer_class = serializers.AccessPointSerializer
347 348 349


class SwitchViewSet(viewsets.ReadOnlyModelViewSet):
350 351
    """Exposes list and details of `topologie.models.Switch` objects.
    """
Maël Kervella's avatar
Maël Kervella committed
352 353
    queryset = topologie.Switch.objects.all()
    serializer_class = serializers.SwitchSerializer
354 355


356 357 358 359 360 361 362
class ServerViewSet(viewsets.ReadOnlyModelViewSet):
    """Exposes list and details of `topologie.models.Server` objects.
    """
    queryset = topologie.Server.objects.all()
    serializer_class = serializers.ServerSerializer


363
class ModelSwitchViewSet(viewsets.ReadOnlyModelViewSet):
364 365
    """Exposes list and details of `topologie.models.ModelSwitch` objects.
    """
Maël Kervella's avatar
Maël Kervella committed
366 367
    queryset = topologie.ModelSwitch.objects.all()
    serializer_class = serializers.ModelSwitchSerializer
368 369 370


class ConstructorSwitchViewSet(viewsets.ReadOnlyModelViewSet):
371 372 373
    """Exposes list and details of `topologie.models.ConstructorSwitch`
    objects.
    """
Maël Kervella's avatar
Maël Kervella committed
374 375
    queryset = topologie.ConstructorSwitch.objects.all()
    serializer_class = serializers.ConstructorSwitchSerializer
376 377 378


class SwitchBayViewSet(viewsets.ReadOnlyModelViewSet):
379 380
    """Exposes list and details of `topologie.models.SwitchBay` objects.
    """
Maël Kervella's avatar
Maël Kervella committed
381 382
    queryset = topologie.SwitchBay.objects.all()
    serializer_class = serializers.SwitchBaySerializer
383 384 385


class BuildingViewSet(viewsets.ReadOnlyModelViewSet):
386 387
    """Exposes list and details of `topologie.models.Building` objects.
    """
Maël Kervella's avatar
Maël Kervella committed
388 389
    queryset = topologie.Building.objects.all()
    serializer_class = serializers.BuildingSerializer
390 391 392


class SwitchPortViewSet(viewsets.ReadOnlyModelViewSet):
393 394
    """Exposes list and details of `topologie.models.Port` objects.
    """
Maël Kervella's avatar
Maël Kervella committed
395 396
    queryset = topologie.Port.objects.all()
    serializer_class = serializers.SwitchPortSerializer
397 398 399


class RoomViewSet(viewsets.ReadOnlyModelViewSet):
400 401
    """Exposes list and details of `topologie.models.Room` objects.
    """
Maël Kervella's avatar
Maël Kervella committed
402 403
    queryset = topologie.Room.objects.all()
    serializer_class = serializers.RoomSerializer
404 405


406 407 408 409 410 411
class PortProfileViewSet(viewsets.ReadOnlyModelViewSet):
    """Exposes list and details of `topologie.models.PortProfile` objects.
    """
    queryset = topologie.PortProfile.objects.all()
    serializer_class = serializers.PortProfileSerializer

412
# USER
413 414


Maël Kervella's avatar
Maël Kervella committed
415
class UserViewSet(viewsets.ReadOnlyModelViewSet):
416 417
    """Exposes list and details of `users.models.Users` objects.
    """
Maël Kervella's avatar
Maël Kervella committed
418 419
    queryset = users.User.objects.all()
    serializer_class = serializers.UserSerializer
Maël Kervella's avatar
Maël Kervella committed
420

421 422 423 424 425
class HomeCreationViewSet(viewsets.ReadOnlyModelViewSet):
    """Exposes infos of `users.models.Users` objects to create homes.
    """
    queryset = users.User.objects.all()
    serializer_class = serializers.HomeCreationSerializer
Maël Kervella's avatar
Maël Kervella committed
426 427

class ClubViewSet(viewsets.ReadOnlyModelViewSet):
428 429
    """Exposes list and details of `users.models.Club` objects.
    """
Maël Kervella's avatar
Maël Kervella committed
430 431
    queryset = users.Club.objects.all()
    serializer_class = serializers.ClubSerializer
Maël Kervella's avatar
Maël Kervella committed
432 433 434


class AdherentViewSet(viewsets.ReadOnlyModelViewSet):
435 436
    """Exposes list and details of `users.models.Adherent` objects.
    """
Maël Kervella's avatar
Maël Kervella committed
437 438
    queryset = users.Adherent.objects.all()
    serializer_class = serializers.AdherentSerializer
Maël Kervella's avatar
Maël Kervella committed
439 440 441


class ServiceUserViewSet(viewsets.ReadOnlyModelViewSet):
442 443
    """Exposes list and details of `users.models.ServiceUser` objects.
    """
Maël Kervella's avatar
Maël Kervella committed
444 445
    queryset = users.ServiceUser.objects.all()
    serializer_class = serializers.ServiceUserSerializer
Maël Kervella's avatar
Maël Kervella committed
446 447 448


class SchoolViewSet(viewsets.ReadOnlyModelViewSet):
449 450
    """Exposes list and details of `users.models.School` objects.
    """
Maël Kervella's avatar
Maël Kervella committed
451 452
    queryset = users.School.objects.all()
    serializer_class = serializers.SchoolSerializer
Maël Kervella's avatar
Maël Kervella committed
453 454 455


class ListRightViewSet(viewsets.ReadOnlyModelViewSet):
456 457
    """Exposes list and details of `users.models.ListRight` objects.
    """
Maël Kervella's avatar
Maël Kervella committed
458 459
    queryset = users.ListRight.objects.all()
    serializer_class = serializers.ListRightSerializer
Maël Kervella's avatar
Maël Kervella committed
460 461 462


class ShellViewSet(viewsets.ReadOnlyModelViewSet):
463 464
    """Exposes list and details of `users.models.ListShell` objects.
    """
Maël Kervella's avatar
Maël Kervella committed
465 466
    queryset = users.ListShell.objects.all()
    serializer_class = serializers.ShellSerializer
Maël Kervella's avatar
Maël Kervella committed
467 468 469


class BanViewSet(viewsets.ReadOnlyModelViewSet):
470 471
    """Exposes list and details of `users.models.Ban` objects.
    """
Maël Kervella's avatar
Maël Kervella committed
472 473
    queryset = users.Ban.objects.all()
    serializer_class = serializers.BanSerializer
Maël Kervella's avatar
Maël Kervella committed
474 475 476


class WhitelistViewSet(viewsets.ReadOnlyModelViewSet):
477 478
    """Exposes list and details of `users.models.Whitelist` objects.
    """
Maël Kervella's avatar
Maël Kervella committed
479 480
    queryset = users.Whitelist.objects.all()
    serializer_class = serializers.WhitelistSerializer
Maël Kervella's avatar
Maël Kervella committed
481

482

483 484
class EMailAddressViewSet(viewsets.ReadOnlyModelViewSet):
    """Exposes list and details of `users.models.EMailAddress` objects.
485
    """
486 487
    serializer_class = serializers.EMailAddressSerializer
    queryset = users.EMailAddress.objects.none()
488 489 490 491

    def get_queryset(self):
        if preferences.OptionalUser.get_cached_value(
            'local_email_accounts_enabled'):
492
            return (users.EMailAddress.objects
493 494
                    .filter(user__local_email_enabled=True))
        else:
495
            return users.EMailAddress.objects.none()
496 497


498
# SERVICE REGEN
499 500


501
class ServiceRegenViewSet(viewsets.ModelViewSet):
502 503
    """Exposes list and details of the services to regen
    """
504 505 506 507 508 509 510 511 512 513 514 515 516 517
    serializer_class = serializers.ServiceRegenSerializer

    def get_queryset(self):
        queryset = machines.Service_link.objects.select_related(
            'server__domain'
        ).select_related(
            'service'
        )
        if 'hostname' in self.request.GET:
            hostname = self.request.GET['hostname']
            queryset = queryset.filter(server__domain__name__iexact=hostname)
        return queryset


518
# LOCAL EMAILS
519 520


521 522
class LocalEmailUsersView(generics.ListAPIView):
    """Exposes all the aliases of the users that activated the internal address
523
    """
524
    serializer_class = serializers.LocalEmailUsersSerializer
525

526 527 528 529 530 531 532
    def get_queryset(self):
        if preferences.OptionalUser.get_cached_value(
            'local_email_accounts_enabled'):
            return (users.User.objects
                    .filter(local_email_enabled=True))
        else:
            return users.User.objects.none()
533 534


535
# DHCP
536

537

538
class HostMacIpView(generics.ListAPIView):
539 540 541
    """Exposes the associations between hostname, mac address and IPv4 in
    order to build the DHCP lease files.
    """
542 543 544 545
    queryset = all_active_interfaces()
    serializer_class = serializers.HostMacIpSerializer


546 547 548 549 550 551
#Firewall

class SubnetPortsOpenView(generics.ListAPIView):
    queryset = machines.IpType.objects.all()
    serializer_class = serializers.SubnetPortsOpenSerializer

552 553 554 555
class InterfacePortsOpenView(generics.ListAPIView):
    queryset = machines.Interface.objects.filter(port_lists__isnull=False).distinct()
    serializer_class = serializers.InterfacePortsOpenSerializer

556
# DNS
557

558

559
class DNSZonesView(generics.ListAPIView):
560
    """Exposes the detailed information about each extension (hostnames,
561 562
    IPs, DNS records, etc.) in order to build the DNS zone files.
    """
563 564 565 566 567 568 569 570
    queryset = (machines.Extension.objects
                .prefetch_related('soa')
                .prefetch_related('ns_set').prefetch_related('ns_set__ns')
                .prefetch_related('origin')
                .prefetch_related('mx_set').prefetch_related('mx_set__name')
                .prefetch_related('txt_set')
                .prefetch_related('srv_set').prefetch_related('srv_set__target')
                .all())
571 572
    serializer_class = serializers.DNSZonesSerializer

573 574 575 576 577 578 579 580 581
class DNSReverseZonesView(generics.ListAPIView):
    """Exposes the detailed information about each extension (hostnames, 
    IPs, DNS records, etc.) in order to build the DNS zone files.
    """
    queryset = (machines.IpType.objects.all())
    serializer_class = serializers.DNSReverseZonesSerializer



582

583
# MAILING
584 585 586


class StandardMailingView(views.APIView):
587 588 589
    """Exposes list and details of standard mailings (name and members) in
    order to building the corresponding mailing lists.
    """
590
    pagination_class = PageSizedPagination
591 592
    permission_classes = (ACLPermission, )
    perms_map = {'GET' : [users.User.can_view_all]}
593 594

    def get(self, request, format=None):
595
        adherents_data = serializers.MailingMemberSerializer(all_has_access(), many=True).data
596 597 598 599 600 601 602
        data = [{'name': 'adherents', 'members': adherents_data}]
        paginator = self.pagination_class()
        paginator.paginate_queryset(data, request)
        return paginator.get_paginated_response(data)


class ClubMailingView(generics.ListAPIView):
603 604 605
    """Exposes list and details of club mailings (name, members and admins) in
    order to build the corresponding mailing lists.
    """
606 607 608 609
    queryset = users.Club.objects.all()
    serializer_class = serializers.MailingSerializer


610 611 612
# TOKEN AUTHENTICATION


613
class ObtainExpiringAuthToken(ObtainAuthToken):
614 615 616 617 618 619
    """Exposes a view to obtain a authentication token.

    This view as the same behavior as the
    `rest_framework.auth_token.views.ObtainAuthToken` view except that the
    expiration time is send along with the token as an addtional information.
    """
620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637
    def post(self, request, *args, **kwargs):
        serializer = self.serializer_class(data=request.data)
        serializer.is_valid(raise_exception=True)
        user = serializer.validated_data['user']
        token, created = Token.objects.get_or_create(user=user)

        token_duration = datetime.timedelta(
            seconds=settings.API_TOKEN_DURATION
        )
        utc_now = datetime.datetime.now(datetime.timezone.utc)
        if not created and token.created < utc_now - token_duration:
            token.delete()
            token = Token.objects.create(user=user)
            token.created = datetime.datetime.utcnow()
            token.save()

        return Response({
            'token': token.key,
638
            'expiration': token.created + token_duration
639
        })