Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / api / tokens.py @ 8cb96389

History | View | Annotate | Download (5.1 kB)

1
# Copyright 2011-2013 GRNET S.A. All rights reserved.
2
#
3
# Redistribution and use in source and binary forms, with or
4
# without modification, are permitted provided that the following
5
# conditions are met:
6
#
7
#   1. Redistributions of source code must retain the above
8
#      copyright notice, this list of conditions and the following
9
#      disclaimer.
10
#
11
#   2. Redistributions in binary form must reproduce the above
12
#      copyright notice, this list of conditions and the following
13
#      disclaimer in the documentation and/or other materials
14
#      provided with the distribution.
15
#
16
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
# POSSIBILITY OF SUCH DAMAGE.
28
#
29
# The views and conclusions contained in the software and
30
# documentation are those of the authors and should not be
31
# interpreted as representing official policies, either expressed
32
# or implied, of GRNET S.A.
33

    
34
from urlparse import urlunsplit, urlsplit
35
from collections import defaultdict
36

    
37
from django.http import urlencode
38
from django.views.decorators.csrf import csrf_exempt
39

    
40
from snf_django.lib.api import faults, utils, api_method
41

    
42
from astakos.im.models import Service, AstakosUser
43
from .util import user_from_token, json_response, xml_response, validate_user
44

    
45
import logging
46
logger = logging.getLogger(__name__)
47

    
48

    
49
@api_method(http_method="GET", token_required=True, user_required=False,
50
            logger=logger)
51
@user_from_token  # Authenticate user!!
52
def get_endpoints(request, token):
53
    if token != request.user.auth_token:
54
        raise faults.Forbidden()
55

    
56
    belongsTo = request.GET.get('belongsTo')
57
    if belongsTo and belongsTo != request.user.uuid:
58
        raise faults.BadRequest()
59

    
60
    marker = request.GET.get('marker', 0)
61
    limit = request.GET.get('limit', 10000)
62

    
63
    endpoints = list(Service.objects.all().order_by('id').
64
                     filter(id__gt=marker)[:limit].
65
                     values('name', 'url', 'api_url', 'id', 'type'))
66
    for e in endpoints:
67
        e['publicURL'] = e['admiURL'] = e['internalURL'] = e['api_url']
68
        e['SNF:uiURL'] = e['url']
69
        e['region'] = e['name']
70
        e.pop('api_url')
71

    
72
    if endpoints:
73
        parts = list(urlsplit(request.path))
74
        params = {'marker': endpoints[-1]['id'], 'limit': limit}
75
        parts[3] = urlencode(params)
76
        next_page_url = urlunsplit(parts)
77
        endpoint_links = [{'href': next_page_url, 'rel': 'next'}]
78
    else:
79
        endpoint_links = []
80

    
81
    result = {'endpoints': endpoints, 'endpoint_links': endpoint_links}
82
    if request.serialization == 'xml':
83
        return xml_response(result, 'api/endpoints.xml')
84
    else:
85
        return json_response(result)
86

    
87

    
88
@csrf_exempt
89
@api_method(http_method="POST", token_required=False, user_required=False,
90
            logger=logger)
91
def authenticate(request):
92
    req = utils.get_request_dict(request)
93

    
94
    uuid = None
95
    try:
96
        token_id = req['auth']['token']['id']
97
    except KeyError:
98
        try:
99
            token_id = req['auth']['passwordCredentials']['password']
100
            uuid = req['auth']['passwordCredentials']['username']
101
        except KeyError:
102
            raise faults.BadRequest('Malformed request')
103

    
104
    if token_id is None:
105
        raise faults.BadRequest('Malformed request')
106

    
107
    try:
108
        user = AstakosUser.objects.get(auth_token=token_id)
109
    except AstakosUser.DoesNotExist:
110
        raise faults.Unauthorized('Invalid token')
111

    
112
    validate_user(user)
113

    
114
    if uuid is not None:
115
        if user.uuid != uuid:
116
            raise faults.Unauthorized('Invalid credentials')
117

    
118
    d = defaultdict(dict)
119
    d["access"]["token"] = {
120
        "id": user.auth_token,
121
        "expires": utils.isoformat(user.auth_token_expires),
122
        "tenant": {"id": user.uuid, "name": user.realname}}
123
    d["access"]["user"] = {
124
        "id": user.uuid, 'name': user.realname,
125
        "roles": list(user.groups.values("id", "name")),
126
        "roles_links": []}
127
    d["access"]["serviceCatalog"] = []
128
    append = d["access"]["serviceCatalog"].append
129
    for s in Service.objects.all().order_by("id"):
130
        endpoints = []
131
        for l in [e.data.values('key', 'value') for e in s.endpoints.all()]:
132
            endpoint = dict((d['key'], d['value']) for d in l)
133
            endpoints.append(endpoint)
134
        append({"name": s.name,
135
                "type": s.type,
136
                "SNF:uiURL": s.component.url,
137
                "endpoints": endpoints,
138
                "endpoints_links": []})
139

    
140
    if request.serialization == 'xml':
141
        return xml_response({'d': d}, 'api/access.xml')
142
    else:
143
        return json_response(d)