Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / api / tokens.py @ ddc6960a

History | View | Annotate | Download (5 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

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

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

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

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

    
47

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

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

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

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

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

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

    
86

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

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

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

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

    
111
    validate_user(user)
112

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

    
117
    access = {}
118
    access['token'] = {'id': user.auth_token,
119
                       'expires': utils.isoformat(user.auth_token_expires),
120
                       'tenant': {'id': user.uuid, 'name': user.realname}}
121
    access['user'] = {'id': user.uuid, 'name': user.realname,
122
                      'roles': list(user.groups.values('id', 'name')),
123
                      'roles_links': []}
124
    access['serviceCatalog'] = []
125
    append = access['serviceCatalog'].append
126
    for s in Service.objects.all().order_by('id'):
127
        append({'name': s.name, 'type': s.type,
128
                'endpoints': [{'adminURL': s.api_url,
129
                               'publicURL': s.api_url,
130
                               'internalURL': s.api_url,
131
                               'SNF:uiURL': s.url,
132
                               'region': s.name}]})
133

    
134
    if request.serialization == 'xml':
135
        return xml_response({'access': access}, 'api/access.xml')
136
    else:
137
        return json_response(access)