Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / api / util.py @ 7ac2131c

History | View | Annotate | Download (6.4 kB)

1
# Copyright 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 functools import wraps
35
from time import time, mktime
36

    
37
from django.http import HttpResponse
38
from django.utils import simplejson as json
39
from django.template.loader import render_to_string
40

    
41
from astakos.im.models import AstakosUser, Service
42
from snf_django.lib.api import faults
43

    
44
from astakos.im.forms import FeedbackForm
45
from astakos.im.functions import send_feedback as send_feedback_func
46

    
47
import logging
48
logger = logging.getLogger(__name__)
49

    
50
absolute = lambda request, url: request.build_absolute_uri(url)
51

    
52

    
53
def json_response(content, status_code=None):
54
    response = HttpResponse()
55
    if status_code is not None:
56
        response.status_code = status_code
57

    
58
    response.content = json.dumps(content)
59
    response['Content-Type'] = 'application/json; charset=UTF-8'
60
    response['Content-Length'] = len(response.content)
61
    return response
62

    
63

    
64
def xml_response(content, template, status_code=None):
65
    response = HttpResponse()
66
    if status_code is not None:
67
        response.status_code = status_code
68

    
69
    response.content = render_to_string(template, content)
70
    response['Content-Type'] = 'application/xml; charset=UTF-8'
71
    response['Content-Length'] = len(response.content)
72
    return response
73

    
74

    
75
def is_integer(x):
76
    return isinstance(x, (int, long))
77

    
78

    
79
def are_integer(lst):
80
    return all(map(is_integer, lst))
81

    
82

    
83
def user_from_token(func):
84
    @wraps(func)
85
    def wrapper(request, *args, **kwargs):
86
        try:
87
            token = request.x_auth_token
88
        except AttributeError:
89
            raise faults.Unauthorized("No authentication token")
90

    
91
        if not token:
92
            raise faults.Unauthorized("Invalid X-Auth-Token")
93

    
94
        try:
95
            user = AstakosUser.objects.get(auth_token=token)
96
        except AstakosUser.DoesNotExist:
97
            raise faults.Unauthorized('Invalid X-Auth-Token')
98

    
99
        # Check if the user is active.
100
        if not user.is_active:
101
            raise faults.Unauthorized('User inactive')
102

    
103
        # Check if the token has expired.
104
        if user.token_expired():
105
            raise faults.Unauthorized('Authentication expired')
106

    
107
        # Check if the user has accepted the terms.
108
        if not user.signed_terms:
109
            raise faults.Unauthorized('Pending approval terms')
110

    
111
        request.user = user
112
        return func(request, *args, **kwargs)
113
    return wrapper
114

    
115

    
116
def service_from_token(func):
117
    """Decorator for authenticating service by it's token.
118

119
    Check that a service with the corresponding token exists. Also,
120
    if service's token has an expiration token, check that it has not
121
    expired.
122

123
    """
124
    @wraps(func)
125
    def wrapper(request, *args, **kwargs):
126
        try:
127
            token = request.x_auth_token
128
        except AttributeError:
129
            raise faults.Unauthorized("No authentication token")
130

    
131
        if not token:
132
            raise faults.Unauthorized("Invalid X-Auth-Token")
133
        try:
134
            service = Service.objects.get(auth_token=token)
135
        except Service.DoesNotExist:
136
            raise faults.Unauthorized("Invalid X-Auth-Token")
137

    
138
        # Check if the token has expired
139
        expiration_date = service.auth_token_expires
140
        if expiration_date:
141
            expires_at = mktime(expiration_date.timetuple())
142
            if time() > expires_at:
143
                raise faults.Unauthorized("Authentication expired")
144

    
145
        request.service_instance = service
146
        return func(request, *args, **kwargs)
147
    return wrapper
148

    
149

    
150
def get_uuid_displayname_catalogs(request, user_call=True):
151
    # Normal Response Codes: 200
152
    # Error Response Codes: BadRequest (400)
153

    
154
    try:
155
        input_data = json.loads(request.raw_post_data)
156
    except:
157
        raise faults.BadRequest('Request body should be json formatted.')
158
    else:
159
        uuids = input_data.get('uuids', [])
160
        if uuids is None and user_call:
161
            uuids = []
162
        displaynames = input_data.get('displaynames', [])
163
        if displaynames is None and user_call:
164
            displaynames = []
165
        user_obj = AstakosUser.objects
166
        d = {'uuid_catalog': user_obj.uuid_catalog(uuids),
167
             'displayname_catalog': user_obj.displayname_catalog(displaynames)}
168

    
169
        response = HttpResponse()
170
        response.content = json.dumps(d)
171
        response['Content-Type'] = 'application/json; charset=UTF-8'
172
        response['Content-Length'] = len(response.content)
173
        return response
174

    
175

    
176
def send_feedback(request, email_template_name='im/feedback_mail.txt'):
177
    form = FeedbackForm(request.POST)
178
    if not form.is_valid():
179
        logger.error("Invalid feedback request: %r", form.errors)
180
        raise faults.BadRequest('Invalid data')
181

    
182
    msg = form.cleaned_data['feedback_msg']
183
    data = form.cleaned_data['feedback_data']
184
    try:
185
        send_feedback_func(msg, data, request.user, email_template_name)
186
    except:
187
        return HttpResponse(status=502)
188
    return HttpResponse(status=200)
189

    
190

    
191
def rename_meta_key(d, old, new):
192
    if old not in d:
193
        return
194
    d[new] = d[old]
195
    del(d[old])