Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (4.4 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 collections import defaultdict
35

    
36
from django.views.decorators.csrf import csrf_exempt
37

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

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

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

    
47

    
48
@csrf_exempt
49
@api_method(http_method="POST", token_required=False, user_required=False,
50
            logger=logger)
51
def authenticate(request):
52
    try:
53
        content_length = get_content_length(request)
54
    except faults.LengthRequired:
55
        content_length = None
56

    
57
    public_mode = True if not content_length else False
58

    
59
    d = defaultdict(dict)
60
    if not public_mode:
61
        req = utils.get_request_dict(request)
62

    
63
        uuid = None
64
        try:
65
            token_id = req['auth']['token']['id']
66
        except KeyError:
67
            try:
68
                token_id = req['auth']['passwordCredentials']['password']
69
                uuid = req['auth']['passwordCredentials']['username']
70
            except KeyError:
71
                raise faults.BadRequest(
72
                    'Malformed request: missing credentials')
73

    
74
        tenant = req['auth'].get('tenantName')
75

    
76
        if token_id is None:
77
            raise faults.BadRequest('Malformed request: missing token')
78

    
79
        try:
80
            user = AstakosUser.objects.get(auth_token=token_id)
81
        except AstakosUser.DoesNotExist:
82
            raise faults.Unauthorized('Invalid token')
83

    
84
        validate_user(user)
85

    
86
        if uuid is not None:
87
            if user.uuid != uuid:
88
                raise faults.Unauthorized('Invalid credentials')
89

    
90
        if tenant is not None:
91
            if user.uuid != tenant:
92
                raise faults.BadRequest('Not conforming tenantName')
93

    
94
        d["access"]["token"] = {
95
            "id": user.auth_token,
96
            "expires": utils.isoformat(user.auth_token_expires),
97
            "tenant": {"id": user.uuid, "name": user.realname}}
98
        d["access"]["user"] = {
99
            "id": user.uuid, 'name': user.realname,
100
            "roles": list(user.groups.values("id", "name")),
101
            "roles_links": []}
102

    
103
    d["access"]["serviceCatalog"] = []
104
    append = d["access"]["serviceCatalog"].append
105
    for s in Service.objects.all().order_by("id"):
106
        endpoints = []
107
        for l in [e.data.values('key', 'value') for e in s.endpoints.all()]:
108
            endpoint = dict((d['key'], d['value']) for d in l)
109
            endpoint["SNF:uiURL"] = s.component.url
110
            if s.name == 'astakos_weblogin':
111
                endpoint["SNF:webloginURL"] = endpoint["publicURL"]
112
            endpoints.append(endpoint)
113
        append({"name": s.name,
114
                "type": s.type,
115
                "endpoints": endpoints,
116
                "endpoints_links": []})
117

    
118
    if request.serialization == 'xml':
119
        return xml_response({'d': d}, 'api/access.xml')
120
    else:
121
        return json_response(d)