Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

# vim: tabstop=4 shiftwidth=4 softtabstop=4 

 

# Copyright 2012 OpenStack LLC 

# 

# Licensed under the Apache License, Version 2.0 (the "License"); you may 

# not use this file except in compliance with the License. You may obtain 

# a copy of the License at 

# 

#      http://www.apache.org/licenses/LICENSE-2.0 

# 

# Unless required by applicable law or agreed to in writing, software 

# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 

# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 

# License for the specific language governing permissions and limitations 

# under the License. 

 

from __future__ import absolute_import 

import copy 

 

import memcache 

 

from keystone.common import utils 

from keystone import config 

from keystone import exception 

from keystone.openstack.common import jsonutils 

from keystone import token 

 

 

CONF = config.CONF 

config.register_str('servers', group='memcache', default='localhost:11211') 

 

 

class Token(token.Driver): 

    revocation_key = 'revocation-list' 

 

    def __init__(self, client=None): 

        self._memcache_client = client 

 

    @property 

    def client(self): 

        return self._memcache_client or self._get_memcache_client() 

 

    def _get_memcache_client(self): 

        memcache_servers = CONF.memcache.servers.split(',') 

        self._memcache_client = memcache.Client(memcache_servers, debug=0) 

        return self._memcache_client 

 

    def _prefix_token_id(self, token_id): 

        return 'token-%s' % token_id.encode('utf-8') 

 

    def _prefix_user_id(self, user_id): 

        return 'usertokens-%s' % user_id.encode('utf-8') 

 

    def get_token(self, token_id): 

        if token_id is None: 

            raise exception.TokenNotFound(token_id='') 

        ptk = self._prefix_token_id(token.unique_id(token_id)) 

        token_ref = self.client.get(ptk) 

        if token_ref is None: 

            raise exception.TokenNotFound(token_id=token_id) 

 

        return token_ref 

 

    def create_token(self, token_id, data): 

        data_copy = copy.deepcopy(data) 

        ptk = self._prefix_token_id(token.unique_id(token_id)) 

        if not data_copy.get('expires'): 

            data_copy['expires'] = token.default_expire_time() 

71        if not data_copy.get('user_id'): 

            data_copy['user_id'] = data_copy['user']['id'] 

        kwargs = {} 

75        if data_copy['expires'] is not None: 

            expires_ts = utils.unixtime(data_copy['expires']) 

            kwargs['time'] = expires_ts 

        self.client.set(ptk, data_copy, **kwargs) 

85        if 'id' in data['user']: 

            token_data = jsonutils.dumps(token_id) 

            user_id = data['user']['id'] 

            user_key = self._prefix_user_id(user_id) 

            if not self.client.append(user_key, ',%s' % token_data): 

82                if not self.client.add(user_key, token_data): 

                    if not self.client.append(user_key, ',%s' % token_data): 

                        msg = _('Unable to add token user list.') 

                        raise exception.UnexpectedError(msg) 

        return copy.deepcopy(data_copy) 

 

    def _add_to_revocation_list(self, data): 

        data_json = jsonutils.dumps(data) 

        if not self.client.append(self.revocation_key, ',%s' % data_json): 

91            if not self.client.add(self.revocation_key, data_json): 

                if not self.client.append(self.revocation_key, 

                                          ',%s' % data_json): 

                    msg = _('Unable to add token to revocation list.') 

                    raise exception.UnexpectedError(msg) 

 

    def delete_token(self, token_id): 

        # Test for existence 

        data = self.get_token(token.unique_id(token_id)) 

        ptk = self._prefix_token_id(token.unique_id(token_id)) 

        result = self.client.delete(ptk) 

        self._add_to_revocation_list(data) 

        return result 

 

    def list_tokens(self, user_id, tenant_id=None, trust_id=None): 

        tokens = [] 

        user_key = self._prefix_user_id(user_id) 

        user_record = self.client.get(user_key) or "" 

        token_list = jsonutils.loads('[%s]' % user_record) 

        for token_id in token_list: 

            ptk = self._prefix_token_id(token.unique_id(token_id)) 

            token_ref = self.client.get(ptk) 

            if token_ref: 

                if tenant_id is not None: 

                    tenant = token_ref.get('tenant') 

                    if not tenant: 

                        continue 

                    if tenant.get('id') != tenant_id: 

                        continue 

                if trust_id is not None: 

                    trust = token_ref.get('trust_id') 

122                    if not trust: 

                        continue 

124                    if trust != trust_id: 

                        continue 

 

                tokens.append(token_id) 

        return tokens 

 

    def list_revoked_tokens(self): 

        list_json = self.client.get(self.revocation_key) 

        if list_json: 

            return jsonutils.loads('[%s]' % list_json) 

        return []