Statistics
| Branch: | Tag: | Revision:

root / snf-django-lib / snf_django / lib / astakos.py @ 0a83201b

History | View | Annotate | Download (5.2 kB)

1 b4b82ec4 Giorgos Korfiatis
# Copyright 2011, 2012, 2013 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 837d85bb Ilias Tsitsimpis
def user_for_token(token, astakos_auth_url, logger=None):
42 ef57e622 Ilias Tsitsimpis
    if token is None:
43 8acb1f97 Kostas Papadimitriou
        return None
44 ef57e622 Ilias Tsitsimpis
    client = AstakosClient(token, astakos_auth_url,
45 ef57e622 Ilias Tsitsimpis
                           retry=2, use_pool=True, logger=logger)
46 8acb1f97 Kostas Papadimitriou
    try:
47 b4b82ec4 Giorgos Korfiatis
        return client.authenticate()
48 81a906f8 Ilias Tsitsimpis
    except Unauthorized:
49 81a906f8 Ilias Tsitsimpis
        return None
50 8acb1f97 Kostas Papadimitriou
51 74d988b0 Christos Stavrakakis
52 837d85bb Ilias Tsitsimpis
def get_user(request, astakos_auth_url, fallback_token=None, logger=None):
53 8acb1f97 Kostas Papadimitriou
    request.user = None
54 8acb1f97 Kostas Papadimitriou
    request.user_uniq = None
55 d65af928 Kostas Papadimitriou
56 8acb1f97 Kostas Papadimitriou
    # Try to find token in a parameter or in a request header.
57 ef57e622 Ilias Tsitsimpis
    user = user_for_token(
58 837d85bb Ilias Tsitsimpis
        request.GET.get('X-Auth-Token'), astakos_auth_url, logger)
59 8acb1f97 Kostas Papadimitriou
    if not user:
60 ef57e622 Ilias Tsitsimpis
        user = user_for_token(
61 837d85bb Ilias Tsitsimpis
            request.META.get('HTTP_X_AUTH_TOKEN'), astakos_auth_url, logger)
62 8acb1f97 Kostas Papadimitriou
    if not user:
63 ef57e622 Ilias Tsitsimpis
        user = user_for_token(
64 837d85bb Ilias Tsitsimpis
            fallback_token, astakos_auth_url, logger)
65 6b5b443b Antony Chazapis
    if not user:
66 7bffb0bd Kostas Papadimitriou
        return None
67 d65af928 Kostas Papadimitriou
68 b4b82ec4 Giorgos Korfiatis
    request.user_uniq = user['access']['user']['id']
69 8acb1f97 Kostas Papadimitriou
    request.user = user
70 83204389 Kostas Papadimitriou
    return user
71 d65af928 Kostas Papadimitriou
72 d65af928 Kostas Papadimitriou
73 76a13815 Christos Stavrakakis
class UserCache(object):
74 76a13815 Christos Stavrakakis
    """uuid<->displayname user 'cache'"""
75 76a13815 Christos Stavrakakis
76 ef57e622 Ilias Tsitsimpis
    def __init__(self, astakos_auth_url, astakos_token,
77 ef57e622 Ilias Tsitsimpis
                 split=100, logger=None):
78 2ea2e173 Stratos Psomadakis
        if logger is None:
79 2ea2e173 Stratos Psomadakis
            logger = logging.getLogger(__name__)
80 2ea2e173 Stratos Psomadakis
        self.logger = logger
81 2ea2e173 Stratos Psomadakis
82 ef57e622 Ilias Tsitsimpis
        self.astakos = AstakosClient(astakos_token, astakos_auth_url,
83 ef57e622 Ilias Tsitsimpis
                                     retry=2, use_pool=True, logger=logger)
84 76a13815 Christos Stavrakakis
        self.users = {}
85 76a13815 Christos Stavrakakis
86 76a13815 Christos Stavrakakis
        self.split = split
87 76a13815 Christos Stavrakakis
        assert(self.split > 0), "split must be positive"
88 76a13815 Christos Stavrakakis
89 76a13815 Christos Stavrakakis
    def fetch_names(self, uuid_list):
90 76a13815 Christos Stavrakakis
        total = len(uuid_list)
91 76a13815 Christos Stavrakakis
        split = self.split
92 2ea2e173 Stratos Psomadakis
        count = 0
93 76a13815 Christos Stavrakakis
94 76a13815 Christos Stavrakakis
        for start in range(0, total, split):
95 76a13815 Christos Stavrakakis
            end = start + split
96 76a13815 Christos Stavrakakis
            try:
97 ef57e622 Ilias Tsitsimpis
                names = \
98 ef57e622 Ilias Tsitsimpis
                    self.astakos.service_get_usernames(uuid_list[start:end])
99 2ea2e173 Stratos Psomadakis
                count += len(names)
100 2ea2e173 Stratos Psomadakis
101 76a13815 Christos Stavrakakis
                self.users.update(names)
102 2ea2e173 Stratos Psomadakis
            except AstakosClientException:
103 81a906f8 Ilias Tsitsimpis
                pass
104 2ea2e173 Stratos Psomadakis
            except Exception as err:
105 2ea2e173 Stratos Psomadakis
                self.logger.error("Unexpected error while fetching "
106 2ea2e173 Stratos Psomadakis
                                  "user display names: %s" % repr(err))
107 2ea2e173 Stratos Psomadakis
108 2ea2e173 Stratos Psomadakis
        diff = (total - count)
109 2ea2e173 Stratos Psomadakis
        assert(diff >= 0), "fetched more displaynames than requested"
110 2ea2e173 Stratos Psomadakis
111 2ea2e173 Stratos Psomadakis
        if diff:
112 2ea2e173 Stratos Psomadakis
            self.logger.debug("Failed to fetch %d displaynames", diff)
113 76a13815 Christos Stavrakakis
114 76a13815 Christos Stavrakakis
    def get_uuid(self, name):
115 2ea2e173 Stratos Psomadakis
        uuid = name
116 2ea2e173 Stratos Psomadakis
117 76a13815 Christos Stavrakakis
        if not name in self.users:
118 76a13815 Christos Stavrakakis
            try:
119 ef57e622 Ilias Tsitsimpis
                uuid = self.astakos.service_get_uuid(name)
120 2ea2e173 Stratos Psomadakis
            except NoUUID:
121 2ea2e173 Stratos Psomadakis
                self.logger.debug("Failed to fetch uuid for %s", name)
122 2ea2e173 Stratos Psomadakis
            except AstakosClientException:
123 2ea2e173 Stratos Psomadakis
                pass
124 2ea2e173 Stratos Psomadakis
            except Exception as err:
125 2ea2e173 Stratos Psomadakis
                self.logger.error("Unexpected error while fetching "
126 2ea2e173 Stratos Psomadakis
                                  "user uuid %s: %s" % (name, repr(err)))
127 2ea2e173 Stratos Psomadakis
            finally:
128 2ea2e173 Stratos Psomadakis
                self.users[name] = uuid
129 76a13815 Christos Stavrakakis
130 76a13815 Christos Stavrakakis
        return self.users[name]
131 76a13815 Christos Stavrakakis
132 76a13815 Christos Stavrakakis
    def get_name(self, uuid):
133 2ea2e173 Stratos Psomadakis
        name = "-"
134 76a13815 Christos Stavrakakis
135 76a13815 Christos Stavrakakis
        if not uuid in self.users:
136 76a13815 Christos Stavrakakis
            try:
137 ef57e622 Ilias Tsitsimpis
                name = self.astakos.service_get_username(uuid)
138 2ea2e173 Stratos Psomadakis
            except NoUserName:
139 2ea2e173 Stratos Psomadakis
                self.logger.debug("Failed to fetch display name for %s", uuid)
140 2ea2e173 Stratos Psomadakis
            except AstakosClientException:
141 2ea2e173 Stratos Psomadakis
                pass
142 2ea2e173 Stratos Psomadakis
            except Exception as err:
143 2ea2e173 Stratos Psomadakis
                self.logger.error("Unexpected error while fetching "
144 2ea2e173 Stratos Psomadakis
                                  "user displayname %s: %s"
145 2ea2e173 Stratos Psomadakis
                                  % (uuid, repr(err)))
146 2ea2e173 Stratos Psomadakis
            finally:
147 2ea2e173 Stratos Psomadakis
                self.users[uuid] = name
148 76a13815 Christos Stavrakakis
149 76a13815 Christos Stavrakakis
        return self.users[uuid]