Statistics
| Branch: | Tag: | Revision:

root / snf-django-lib / snf_django / lib / astakos.py @ c7e03d20

History | View | Annotate | Download (5.4 kB)

1 8acb1f97 Kostas Papadimitriou
# Copyright 2011-2012 GRNET S.A. All rights reserved.
2 d65af928 Kostas Papadimitriou
#
3 8acb1f97 Kostas Papadimitriou
# Redistribution and use in source and binary forms, with or
4 8acb1f97 Kostas Papadimitriou
# without modification, are permitted provided that the following
5 8acb1f97 Kostas Papadimitriou
# conditions are met:
6 d65af928 Kostas Papadimitriou
#
7 8acb1f97 Kostas Papadimitriou
#   1. Redistributions of source code must retain the above
8 8acb1f97 Kostas Papadimitriou
#      copyright notice, this list of conditions and the following
9 8acb1f97 Kostas Papadimitriou
#      disclaimer.
10 d65af928 Kostas Papadimitriou
#
11 8acb1f97 Kostas Papadimitriou
#   2. Redistributions in binary form must reproduce the above
12 8acb1f97 Kostas Papadimitriou
#      copyright notice, this list of conditions and the following
13 8acb1f97 Kostas Papadimitriou
#      disclaimer in the documentation and/or other materials
14 8acb1f97 Kostas Papadimitriou
#      provided with the distribution.
15 d65af928 Kostas Papadimitriou
#
16 8acb1f97 Kostas Papadimitriou
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 8acb1f97 Kostas Papadimitriou
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 8acb1f97 Kostas Papadimitriou
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 8acb1f97 Kostas Papadimitriou
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 8acb1f97 Kostas Papadimitriou
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 8acb1f97 Kostas Papadimitriou
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 8acb1f97 Kostas Papadimitriou
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 8acb1f97 Kostas Papadimitriou
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 8acb1f97 Kostas Papadimitriou
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 8acb1f97 Kostas Papadimitriou
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 8acb1f97 Kostas Papadimitriou
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 8acb1f97 Kostas Papadimitriou
# POSSIBILITY OF SUCH DAMAGE.
28 d65af928 Kostas Papadimitriou
#
29 8acb1f97 Kostas Papadimitriou
# The views and conclusions contained in the software and
30 8acb1f97 Kostas Papadimitriou
# documentation are those of the authors and should not be
31 8acb1f97 Kostas Papadimitriou
# interpreted as representing official policies, either expressed
32 8acb1f97 Kostas Papadimitriou
# or implied, of GRNET S.A.
33 8acb1f97 Kostas Papadimitriou
34 2ea2e173 Stratos Psomadakis
import logging
35 2ea2e173 Stratos Psomadakis
36 81a906f8 Ilias Tsitsimpis
from astakosclient import AstakosClient
37 2ea2e173 Stratos Psomadakis
from astakosclient.errors import (Unauthorized, NoUUID, NoUserName,
38 2ea2e173 Stratos Psomadakis
                                  AstakosClientException)
39 83204389 Kostas Papadimitriou
40 8acb1f97 Kostas Papadimitriou
41 81a906f8 Ilias Tsitsimpis
def user_for_token(client, token, usage=False):
42 8acb1f97 Kostas Papadimitriou
    if not token:
43 8acb1f97 Kostas Papadimitriou
        return None
44 d65af928 Kostas Papadimitriou
45 8acb1f97 Kostas Papadimitriou
    try:
46 81a906f8 Ilias Tsitsimpis
        return client.get_user_info(token, usage=True)
47 81a906f8 Ilias Tsitsimpis
    except Unauthorized:
48 81a906f8 Ilias Tsitsimpis
        return None
49 8acb1f97 Kostas Papadimitriou
50 74d988b0 Christos Stavrakakis
51 81a906f8 Ilias Tsitsimpis
def get_user(request, astakos_url, fallback_token=None,
52 81a906f8 Ilias Tsitsimpis
             usage=False, logger=None):
53 8acb1f97 Kostas Papadimitriou
    request.user = None
54 8acb1f97 Kostas Papadimitriou
    request.user_uniq = None
55 d65af928 Kostas Papadimitriou
56 81a906f8 Ilias Tsitsimpis
    client = AstakosClient(astakos_url, retry=2, use_pool=True, logger=logger)
57 8acb1f97 Kostas Papadimitriou
    # Try to find token in a parameter or in a request header.
58 81a906f8 Ilias Tsitsimpis
    user = user_for_token(client, request.GET.get('X-Auth-Token'), usage=usage)
59 8acb1f97 Kostas Papadimitriou
    if not user:
60 81a906f8 Ilias Tsitsimpis
        user = user_for_token(client,
61 81a906f8 Ilias Tsitsimpis
                              request.META.get('HTTP_X_AUTH_TOKEN'),
62 81a906f8 Ilias Tsitsimpis
                              usage=usage)
63 8acb1f97 Kostas Papadimitriou
    if not user:
64 81a906f8 Ilias Tsitsimpis
        user = user_for_token(client, fallback_token, usage=usage)
65 6b5b443b Antony Chazapis
    if not user:
66 7bffb0bd Kostas Papadimitriou
        return None
67 d65af928 Kostas Papadimitriou
68 74d988b0 Christos Stavrakakis
    # use user uuid, instead of email, keep email/displayname reference
69 74d988b0 Christos Stavrakakis
    # to user_id
70 83204389 Kostas Papadimitriou
    request.user_uniq = user['uuid']
71 8acb1f97 Kostas Papadimitriou
    request.user = user
72 890c2065 Sofia Papagiannaki
    request.user_id = user.get('displayname')
73 83204389 Kostas Papadimitriou
    return user
74 d65af928 Kostas Papadimitriou
75 d65af928 Kostas Papadimitriou
76 76a13815 Christos Stavrakakis
class UserCache(object):
77 76a13815 Christos Stavrakakis
    """uuid<->displayname user 'cache'"""
78 76a13815 Christos Stavrakakis
79 81a906f8 Ilias Tsitsimpis
    def __init__(self, astakos_url, astakos_token, split=100, logger=None):
80 2ea2e173 Stratos Psomadakis
        if logger is None:
81 2ea2e173 Stratos Psomadakis
            logger = logging.getLogger(__name__)
82 2ea2e173 Stratos Psomadakis
        self.logger = logger
83 2ea2e173 Stratos Psomadakis
84 81a906f8 Ilias Tsitsimpis
        self.astakos = AstakosClient(astakos_url, retry=2,
85 81a906f8 Ilias Tsitsimpis
                                     use_pool=True, logger=logger)
86 76a13815 Christos Stavrakakis
        self.astakos_token = astakos_token
87 76a13815 Christos Stavrakakis
        self.users = {}
88 76a13815 Christos Stavrakakis
89 76a13815 Christos Stavrakakis
        self.split = split
90 76a13815 Christos Stavrakakis
        assert(self.split > 0), "split must be positive"
91 76a13815 Christos Stavrakakis
92 76a13815 Christos Stavrakakis
    def fetch_names(self, uuid_list):
93 76a13815 Christos Stavrakakis
        total = len(uuid_list)
94 76a13815 Christos Stavrakakis
        split = self.split
95 2ea2e173 Stratos Psomadakis
        count = 0
96 76a13815 Christos Stavrakakis
97 76a13815 Christos Stavrakakis
        for start in range(0, total, split):
98 76a13815 Christos Stavrakakis
            end = start + split
99 76a13815 Christos Stavrakakis
            try:
100 81a906f8 Ilias Tsitsimpis
                names = self.astakos.service_get_usernames(
101 81a906f8 Ilias Tsitsimpis
                    self.astakos_token, uuid_list[start:end])
102 2ea2e173 Stratos Psomadakis
                count += len(names)
103 2ea2e173 Stratos Psomadakis
104 76a13815 Christos Stavrakakis
                self.users.update(names)
105 2ea2e173 Stratos Psomadakis
            except AstakosClientException:
106 81a906f8 Ilias Tsitsimpis
                pass
107 2ea2e173 Stratos Psomadakis
            except Exception as err:
108 2ea2e173 Stratos Psomadakis
                self.logger.error("Unexpected error while fetching "
109 2ea2e173 Stratos Psomadakis
                                  "user display names: %s" % repr(err))
110 2ea2e173 Stratos Psomadakis
111 2ea2e173 Stratos Psomadakis
        diff = (total - count)
112 2ea2e173 Stratos Psomadakis
        assert(diff >= 0), "fetched more displaynames than requested"
113 2ea2e173 Stratos Psomadakis
114 2ea2e173 Stratos Psomadakis
        if diff:
115 2ea2e173 Stratos Psomadakis
            self.logger.debug("Failed to fetch %d displaynames", diff)
116 76a13815 Christos Stavrakakis
117 76a13815 Christos Stavrakakis
    def get_uuid(self, name):
118 2ea2e173 Stratos Psomadakis
        uuid = name
119 2ea2e173 Stratos Psomadakis
120 76a13815 Christos Stavrakakis
        if not name in self.users:
121 76a13815 Christos Stavrakakis
            try:
122 2ea2e173 Stratos Psomadakis
                uuid = self.astakos.service_get_uuid(
123 2ea2e173 Stratos Psomadakis
                    self.astakos_token, name)
124 2ea2e173 Stratos Psomadakis
            except NoUUID:
125 2ea2e173 Stratos Psomadakis
                self.logger.debug("Failed to fetch uuid for %s", name)
126 2ea2e173 Stratos Psomadakis
            except AstakosClientException:
127 2ea2e173 Stratos Psomadakis
                pass
128 2ea2e173 Stratos Psomadakis
            except Exception as err:
129 2ea2e173 Stratos Psomadakis
                self.logger.error("Unexpected error while fetching "
130 2ea2e173 Stratos Psomadakis
                                  "user uuid %s: %s" % (name, repr(err)))
131 2ea2e173 Stratos Psomadakis
            finally:
132 2ea2e173 Stratos Psomadakis
                self.users[name] = uuid
133 76a13815 Christos Stavrakakis
134 76a13815 Christos Stavrakakis
        return self.users[name]
135 76a13815 Christos Stavrakakis
136 76a13815 Christos Stavrakakis
    def get_name(self, uuid):
137 2ea2e173 Stratos Psomadakis
        name = "-"
138 76a13815 Christos Stavrakakis
139 76a13815 Christos Stavrakakis
        if not uuid in self.users:
140 76a13815 Christos Stavrakakis
            try:
141 2ea2e173 Stratos Psomadakis
                name = self.astakos.service_get_username(
142 2ea2e173 Stratos Psomadakis
                    self.astakos_token, uuid)
143 2ea2e173 Stratos Psomadakis
            except NoUserName:
144 2ea2e173 Stratos Psomadakis
                self.logger.debug("Failed to fetch display name for %s", uuid)
145 2ea2e173 Stratos Psomadakis
            except AstakosClientException:
146 2ea2e173 Stratos Psomadakis
                pass
147 2ea2e173 Stratos Psomadakis
            except Exception as err:
148 2ea2e173 Stratos Psomadakis
                self.logger.error("Unexpected error while fetching "
149 2ea2e173 Stratos Psomadakis
                                  "user displayname %s: %s"
150 2ea2e173 Stratos Psomadakis
                                  % (uuid, repr(err)))
151 2ea2e173 Stratos Psomadakis
            finally:
152 2ea2e173 Stratos Psomadakis
                self.users[uuid] = name
153 76a13815 Christos Stavrakakis
154 76a13815 Christos Stavrakakis
        return self.users[uuid]