client_views.py 3.51 KB
Newer Older
1
2

import logging
3
import re
4
5
from django.http import HttpResponse
from django.contrib.auth import authenticate
6
from ...models import User, RabbitMQInstance
7
8
9

LOGGER = logging.getLogger(__name__)

10

11
def _valid_vhost(request):
12
13
14
15
16
    if 'vhost' in request.POST and request.POST['vhost'] == RabbitMQInstance.load().vhost:
        return True
    LOGGER.error('illegal vhost requested')
    return False

17
def _valid_permission(request):
18
19
20
21
22
    if 'permission' in request.POST and request.POST['permission'] != 'write':
        return True
    LOGGER.error('illegal permission requested')
    return False

23
24
25
26
27
28
29
30
31
32
33
def _valid_user(request):
    if 'username' in request.POST:
        valid = User.objects.filter(
            user_type='apiclient',
            username=request.POST['username'],
        ).exists()
        if valid:
            return True
    LOGGER.error('illegal user requested')
    return False

34
35
def _get_user(request):
    if 'username' in request.POST:
36
37
38
39
        user = User.objects.filter(user_type='apiclient').get(username=request.POST['username'])
        if user:
            return user
    LOGGER.error('unable to get user for request')
40
41
    return None

42
43
# VIEWS

44
# client authentication for RabbitMQ
45
46
47
48
49
50
51
def user_endpoint(request):
    if 'username' in request.POST and 'password' in request.POST:
        username = request.POST['username']
        password = request.POST['password']
        user = authenticate(username=username, password=password)
        if user:
            LOGGER.info('Authenticated client as %s', user)
52
            return HttpResponse("allow")
53
54
55
56

    LOGGER.error('Failed to authenticate user for RabbitMQ')
    return HttpResponse("deny")

57
58

# client authorization checks for RabbitMQ
59
def vhost(request):
60
    # check if on the correct virtual host
61
    if _valid_vhost(request) and _valid_user(request):
62
63
64
65
        return HttpResponse("allow")

    LOGGER.error('Authorization check for vhost failed for %s', request.POST)
    return HttpResponse("deny")
66
67

def resource(request):
68
69
70
71
72
73
74
75
76
77
78
79
80
81
    if not _valid_vhost(request) or not _valid_user(request):
        return HttpResponse('deny')

    if 'resource' in request.POST and 'name' in request.POST:
        if request.POST['resource'] == 'queue':
            # the temporary queue a client binds to our exchange
            if request.POST['name'].startswith('amq.gen-'):
                return HttpResponse('allow')
        elif request.POST['resource'] == 'exchange' and _valid_permission(request):
            # our exchange
            if request.POST['name'] == RabbitMQInstance.load().exchange:
                return HttpResponse('allow')
        elif request.POST['resource'] == 'topic' and _valid_permission(request):
            pass
82
83

    LOGGER.error('Authorization check for resource failed for %s', request.POST)
84
    return HttpResponse('deny')
85

86
87

def topic(request):
88
    # check if on the correct virtual host
89
90
91
92
93
94
95
96
97
98
99
100
101
102
    if not _valid_vhost(request) or not _valid_permission(request) or not _valid_user(request):
        return HttpResponse('deny')

    user = _get_user(request)
    if user and 'routing_key' in request.POST:
        routing_key = request.POST['routing_key']
        if routing_key.startswith('service.'):
            match = re.search('service.(.+)', routing_key)
            if match:
                service_name = match.group(1)
                for service in user.site.services.all():
                    if service_name == service.name:
                        return HttpResponse('allow')

103
104
    LOGGER.error('Authorization check for topic failed for %s', request.POST)
    return HttpResponse('deny')