Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / helpdesk / views.py @ 9fd36718

History | View | Annotate | Download (4.4 kB)

1 d59d86d4 Kostas Papadimitriou
import re
2 d59d86d4 Kostas Papadimitriou
3 9e3519e0 Kostas Papadimitriou
from itertools import chain
4 9e3519e0 Kostas Papadimitriou
5 d59d86d4 Kostas Papadimitriou
from django.shortcuts import redirect, get_object_or_404
6 c3564ce9 Kostas Papadimitriou
from django.views.generic.simple import direct_to_template
7 e129e26b Kostas Papadimitriou
from django.db.models import get_apps
8 e129e26b Kostas Papadimitriou
from django.conf import settings
9 e129e26b Kostas Papadimitriou
from django.core.exceptions import PermissionDenied
10 e129e26b Kostas Papadimitriou
from django.db.models import Q
11 9e3519e0 Kostas Papadimitriou
from django.http import Http404, HttpResponse
12 9e3519e0 Kostas Papadimitriou
from django.utils import simplejson as json
13 ebda2ad4 Kostas Papadimitriou
from urllib import unquote
14 c3564ce9 Kostas Papadimitriou
15 ebda2ad4 Kostas Papadimitriou
from synnefo.lib.astakos import get_user
16 9e3519e0 Kostas Papadimitriou
from synnefo.db.models import *
17 e129e26b Kostas Papadimitriou
18 d59d86d4 Kostas Papadimitriou
IP_SEARCH_REGEX = re.compile('([0-9]+)(?:\.[0-9]+){3}')
19 d59d86d4 Kostas Papadimitriou
20 ebda2ad4 Kostas Papadimitriou
def get_token_from_cookie(request, cookiename):
21 ebda2ad4 Kostas Papadimitriou
    """
22 ebda2ad4 Kostas Papadimitriou
    Extract token from the cookie name provided. Cookie should be in the same
23 ebda2ad4 Kostas Papadimitriou
    form as astakos service sets its cookie contents::
24 ebda2ad4 Kostas Papadimitriou

25 ebda2ad4 Kostas Papadimitriou
        <user_uniq>|<user_token>
26 ebda2ad4 Kostas Papadimitriou
    """
27 ebda2ad4 Kostas Papadimitriou
    try:
28 ebda2ad4 Kostas Papadimitriou
        cookie_content = unquote(request.COOKIES.get(cookiename, None))
29 ebda2ad4 Kostas Papadimitriou
        return cookie_content.split("|")[1]
30 ebda2ad4 Kostas Papadimitriou
    except AttributeError:
31 ebda2ad4 Kostas Papadimitriou
        pass
32 ebda2ad4 Kostas Papadimitriou
33 ebda2ad4 Kostas Papadimitriou
    return None
34 ebda2ad4 Kostas Papadimitriou
35 9fd36718 Kostas Papadimitriou
36 9e3519e0 Kostas Papadimitriou
# TODO: here we mix ui setting with helpdesk settings
37 e129e26b Kostas Papadimitriou
# if sometime in the future helpdesk gets splitted from the
38 e129e26b Kostas Papadimitriou
# cyclades api code this should change and helpdesk should provide
39 9e3519e0 Kostas Papadimitriou
# its own setting HELPDESK_AUTH_COOKIE_NAME.
40 9fd36718 Kostas Papadimitriou
AUTH_COOKIE = getattr(settings, 'UI_AUTH_COOKIE_NAME', getattr(settings,
41 9fd36718 Kostas Papadimitriou
    'HELPDESK_AUTH_COOKIE_NAME', '_pithos2_a'))
42 9fd36718 Kostas Papadimitriou
43 e129e26b Kostas Papadimitriou
44 e129e26b Kostas Papadimitriou
def helpdesk_user_required(func, groups=['helpdesk']):
45 e129e26b Kostas Papadimitriou
    """
46 e129e26b Kostas Papadimitriou
    Django view wrapper that checks if identified request user has helpdesk
47 e129e26b Kostas Papadimitriou
    permissions (exists in helpdesk group)
48 e129e26b Kostas Papadimitriou
    """
49 e129e26b Kostas Papadimitriou
    def wrapper(request, *args, **kwargs):
50 9fd36718 Kostas Papadimitriou
        HELPDESK_ENABLED = getattr(settings, 'HELPDESK_ENABLED', True)
51 9fd36718 Kostas Papadimitriou
        if not HELPDESK_ENABLED:
52 9fd36718 Kostas Papadimitriou
            raise Http404
53 9fd36718 Kostas Papadimitriou
54 9fd36718 Kostas Papadimitriou
        token = get_token_from_cookie(request, AUTH_COOKIE)
55 e129e26b Kostas Papadimitriou
        get_user(request, settings.ASTAKOS_URL, fallback_token=token)
56 9e3519e0 Kostas Papadimitriou
        if hasattr(request, 'user') and request.user:
57 e129e26b Kostas Papadimitriou
            groups = request.user.get('groups', [])
58 0e5c88d0 Kostas Papadimitriou
59 0e5c88d0 Kostas Papadimitriou
            if not groups:
60 0e5c88d0 Kostas Papadimitriou
                raise PermissionDenied
61 0e5c88d0 Kostas Papadimitriou
62 e129e26b Kostas Papadimitriou
            for g in groups:
63 e129e26b Kostas Papadimitriou
                if not g in groups:
64 e129e26b Kostas Papadimitriou
                    raise PermissionDenied
65 e129e26b Kostas Papadimitriou
        else:
66 e129e26b Kostas Papadimitriou
            raise PermissionDenied
67 e129e26b Kostas Papadimitriou
68 e129e26b Kostas Papadimitriou
        return func(request, *args, **kwargs)
69 e129e26b Kostas Papadimitriou
70 e129e26b Kostas Papadimitriou
    return wrapper
71 e129e26b Kostas Papadimitriou
72 e129e26b Kostas Papadimitriou
73 e129e26b Kostas Papadimitriou
@helpdesk_user_required
74 c3564ce9 Kostas Papadimitriou
def index(request):
75 c3564ce9 Kostas Papadimitriou
    """
76 c3564ce9 Kostas Papadimitriou
    Helpdesk index view.
77 c3564ce9 Kostas Papadimitriou
    """
78 e129e26b Kostas Papadimitriou
79 c3564ce9 Kostas Papadimitriou
    # if form submitted redirect to details
80 c3564ce9 Kostas Papadimitriou
    account = request.GET.get('account', None)
81 c3564ce9 Kostas Papadimitriou
    if account:
82 d59d86d4 Kostas Papadimitriou
        return redirect('synnefo.helpdesk.views.account', account_or_ip=account)
83 c3564ce9 Kostas Papadimitriou
84 c3564ce9 Kostas Papadimitriou
    # show index template
85 c3564ce9 Kostas Papadimitriou
    return direct_to_template(request, "helpdesk/index.html")
86 c3564ce9 Kostas Papadimitriou
87 c3564ce9 Kostas Papadimitriou
88 e129e26b Kostas Papadimitriou
@helpdesk_user_required
89 d59d86d4 Kostas Papadimitriou
def account(request, account_or_ip):
90 c3564ce9 Kostas Papadimitriou
    """
91 e129e26b Kostas Papadimitriou
    Account details view.
92 c3564ce9 Kostas Papadimitriou
    """
93 e129e26b Kostas Papadimitriou
94 9e3519e0 Kostas Papadimitriou
    account_exists = True
95 d59d86d4 Kostas Papadimitriou
    vms = []
96 d59d86d4 Kostas Papadimitriou
    networks = []
97 d59d86d4 Kostas Papadimitriou
    is_ip = IP_SEARCH_REGEX.match(account_or_ip)
98 d59d86d4 Kostas Papadimitriou
    account = account_or_ip
99 d59d86d4 Kostas Papadimitriou
100 d59d86d4 Kostas Papadimitriou
    if is_ip:
101 d59d86d4 Kostas Papadimitriou
        try:
102 d59d86d4 Kostas Papadimitriou
            nic = NetworkInterface.objects.get(ipv4=account_or_ip)
103 d59d86d4 Kostas Papadimitriou
            account = nic.machine.userid
104 d59d86d4 Kostas Papadimitriou
        except NetworkInterface.DoesNotExist:
105 d59d86d4 Kostas Papadimitriou
            account_exists = False
106 d59d86d4 Kostas Papadimitriou
    else:
107 d59d86d4 Kostas Papadimitriou
        # all user vms
108 d59d86d4 Kostas Papadimitriou
        vms = VirtualMachine.objects.filter(userid=account).order_by('deleted')
109 d59d86d4 Kostas Papadimitriou
110 d59d86d4 Kostas Papadimitriou
        # return all user private and public networks
111 d59d86d4 Kostas Papadimitriou
        public_networks = Network.objects.filter(public=True).order_by('state')
112 d59d86d4 Kostas Papadimitriou
        private_networks = Network.objects.filter(userid=account).order_by('state')
113 d59d86d4 Kostas Papadimitriou
        networks = list(public_networks) + list(private_networks)
114 d59d86d4 Kostas Papadimitriou
115 d59d86d4 Kostas Papadimitriou
        if vms.count() == 0 and private_networks.count() == 0:
116 d59d86d4 Kostas Papadimitriou
            account_exists = False
117 e129e26b Kostas Papadimitriou
118 c3564ce9 Kostas Papadimitriou
    user_context = {
119 9e3519e0 Kostas Papadimitriou
        'account_exists': account_exists,
120 d59d86d4 Kostas Papadimitriou
        'is_ip': is_ip,
121 c3564ce9 Kostas Papadimitriou
        'account': account,
122 9e3519e0 Kostas Papadimitriou
        'vms': vms,
123 c3564ce9 Kostas Papadimitriou
        'networks': networks,
124 e620ca07 Olga Brani
        'UI_MEDIA_URL': settings.UI_MEDIA_URL
125 c3564ce9 Kostas Papadimitriou
    }
126 d59d86d4 Kostas Papadimitriou
127 c3564ce9 Kostas Papadimitriou
    return direct_to_template(request, "helpdesk/account.html",
128 c3564ce9 Kostas Papadimitriou
        extra_context=user_context)
129 c3564ce9 Kostas Papadimitriou
130 ebda2ad4 Kostas Papadimitriou
131 9e3519e0 Kostas Papadimitriou
@helpdesk_user_required
132 9e3519e0 Kostas Papadimitriou
def user_list(request):
133 9e3519e0 Kostas Papadimitriou
    """
134 9e3519e0 Kostas Papadimitriou
    Return a json list of users based on the prefix provided. Prefix
135 9e3519e0 Kostas Papadimitriou
    should end with "@".
136 9e3519e0 Kostas Papadimitriou
    """
137 9e3519e0 Kostas Papadimitriou
138 9e3519e0 Kostas Papadimitriou
    prefix = request.GET.get('prefix', None)
139 ebda2ad4 Kostas Papadimitriou
    if not prefix or "@" not in prefix:
140 9e3519e0 Kostas Papadimitriou
        raise Http404
141 9e3519e0 Kostas Papadimitriou
142 ebda2ad4 Kostas Papadimitriou
    # keep only the user part (e.g. "user@")
143 ebda2ad4 Kostas Papadimitriou
    prefix = prefix.split("@")[0] + "@"
144 ebda2ad4 Kostas Papadimitriou
145 9e3519e0 Kostas Papadimitriou
    q = Q(userid__startswith=prefix) & ~Q(userid=None)
146 9e3519e0 Kostas Papadimitriou
    vm_users = VirtualMachine.objects.filter(q).values_list("userid", flat=True)
147 9e3519e0 Kostas Papadimitriou
    net_users = Network.objects.filter(q).values_list("userid", flat=True)
148 9e3519e0 Kostas Papadimitriou
    users = list(set(list(vm_users) + list(net_users)))
149 9e3519e0 Kostas Papadimitriou
    return HttpResponse(json.dumps(users), content_type="application/json")