##// END OF EJS Templates
user-sessions: added an API call to cleanup sessions.
marcink -
r1367:11dec75f default
parent child Browse files
Show More
@@ -0,0 +1,44 b''
1 # -*- coding: utf-8 -*-
2
3 # Copyright (C) 2017-2017 RhodeCode GmbH
4 #
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
21 import mock
22 import pytest
23
24 from rhodecode.lib.user_sessions import FileAuthSessions
25 from rhodecode.api.tests.utils import (
26 build_data, api_call, assert_ok, assert_error, crash)
27
28
29 @pytest.mark.usefixtures("testuser_api", "app")
30 class TestCleanupSessions(object):
31 def test_api_cleanup_sessions(self):
32 id_, params = build_data(self.apikey, 'cleanup_sessions')
33 response = api_call(self.app, params)
34
35 expected = {'backend': 'file sessions', 'sessions_removed': 0}
36 assert_ok(id_, expected, given=response.body)
37
38 @mock.patch.object(FileAuthSessions, 'clean_sessions', crash)
39 def test_api_cleanup_error(self):
40 id_, params = build_data(self.apikey, 'cleanup_sessions', )
41 response = api_call(self.app, params)
42
43 expected = 'Error occurred during session cleanup'
44 assert_error(id_, expected, given=response.body)
@@ -1,178 +1,244 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2011-2017 RhodeCode GmbH
3 # Copyright (C) 2011-2017 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21
21
22 import logging
22 import logging
23
23
24 from rhodecode.api import jsonrpc_method, JSONRPCError, JSONRPCForbidden
24 from rhodecode.api import jsonrpc_method, JSONRPCError, JSONRPCForbidden
25
25
26 from rhodecode.api.utils import (
26 from rhodecode.api.utils import (
27 Optional, OAttr, has_superadmin_permission, get_user_or_error)
27 Optional, OAttr, has_superadmin_permission, get_user_or_error)
28 from rhodecode.lib.utils import repo2db_mapper
28 from rhodecode.lib.utils import repo2db_mapper
29 from rhodecode.lib import system_info
30 from rhodecode.lib import user_sessions
29 from rhodecode.model.db import UserIpMap
31 from rhodecode.model.db import UserIpMap
30 from rhodecode.model.scm import ScmModel
32 from rhodecode.model.scm import ScmModel
31
33
32 log = logging.getLogger(__name__)
34 log = logging.getLogger(__name__)
33
35
34
36
35 @jsonrpc_method()
37 @jsonrpc_method()
36 def get_server_info(request, apiuser):
38 def get_server_info(request, apiuser):
37 """
39 """
38 Returns the |RCE| server information.
40 Returns the |RCE| server information.
39
41
40 This includes the running version of |RCE| and all installed
42 This includes the running version of |RCE| and all installed
41 packages. This command takes the following options:
43 packages. This command takes the following options:
42
44
43 :param apiuser: This is filled automatically from the |authtoken|.
45 :param apiuser: This is filled automatically from the |authtoken|.
44 :type apiuser: AuthUser
46 :type apiuser: AuthUser
45
47
46 Example output:
48 Example output:
47
49
48 .. code-block:: bash
50 .. code-block:: bash
49
51
50 id : <id_given_in_input>
52 id : <id_given_in_input>
51 result : {
53 result : {
52 'modules': [<module name>,...]
54 'modules': [<module name>,...]
53 'py_version': <python version>,
55 'py_version': <python version>,
54 'platform': <platform type>,
56 'platform': <platform type>,
55 'rhodecode_version': <rhodecode version>
57 'rhodecode_version': <rhodecode version>
56 }
58 }
57 error : null
59 error : null
58 """
60 """
59
61
60 if not has_superadmin_permission(apiuser):
62 if not has_superadmin_permission(apiuser):
61 raise JSONRPCForbidden()
63 raise JSONRPCForbidden()
62
64
63 server_info = ScmModel().get_server_info(request.environ)
65 server_info = ScmModel().get_server_info(request.environ)
64 # rhodecode-index requires those
66 # rhodecode-index requires those
65
67
66 server_info['index_storage'] = server_info['search']['value']['location']
68 server_info['index_storage'] = server_info['search']['value']['location']
67 server_info['storage'] = server_info['storage']['value']['path']
69 server_info['storage'] = server_info['storage']['value']['path']
68
70
69 return server_info
71 return server_info
70
72
71
73
72 @jsonrpc_method()
74 @jsonrpc_method()
73 def get_ip(request, apiuser, userid=Optional(OAttr('apiuser'))):
75 def get_ip(request, apiuser, userid=Optional(OAttr('apiuser'))):
74 """
76 """
75 Displays the IP Address as seen from the |RCE| server.
77 Displays the IP Address as seen from the |RCE| server.
76
78
77 * This command displays the IP Address, as well as all the defined IP
79 * This command displays the IP Address, as well as all the defined IP
78 addresses for the specified user. If the ``userid`` is not set, the
80 addresses for the specified user. If the ``userid`` is not set, the
79 data returned is for the user calling the method.
81 data returned is for the user calling the method.
80
82
81 This command can only be run using an |authtoken| with admin rights to
83 This command can only be run using an |authtoken| with admin rights to
82 the specified repository.
84 the specified repository.
83
85
84 This command takes the following options:
86 This command takes the following options:
85
87
86 :param apiuser: This is filled automatically from |authtoken|.
88 :param apiuser: This is filled automatically from |authtoken|.
87 :type apiuser: AuthUser
89 :type apiuser: AuthUser
88 :param userid: Sets the userid for which associated IP Address data
90 :param userid: Sets the userid for which associated IP Address data
89 is returned.
91 is returned.
90 :type userid: Optional(str or int)
92 :type userid: Optional(str or int)
91
93
92 Example output:
94 Example output:
93
95
94 .. code-block:: bash
96 .. code-block:: bash
95
97
96 id : <id_given_in_input>
98 id : <id_given_in_input>
97 result : {
99 result : {
98 "server_ip_addr": "<ip_from_clien>",
100 "server_ip_addr": "<ip_from_clien>",
99 "user_ips": [
101 "user_ips": [
100 {
102 {
101 "ip_addr": "<ip_with_mask>",
103 "ip_addr": "<ip_with_mask>",
102 "ip_range": ["<start_ip>", "<end_ip>"],
104 "ip_range": ["<start_ip>", "<end_ip>"],
103 },
105 },
104 ...
106 ...
105 ]
107 ]
106 }
108 }
107
109
108 """
110 """
109 if not has_superadmin_permission(apiuser):
111 if not has_superadmin_permission(apiuser):
110 raise JSONRPCForbidden()
112 raise JSONRPCForbidden()
111
113
112 userid = Optional.extract(userid, evaluate_locals=locals())
114 userid = Optional.extract(userid, evaluate_locals=locals())
113 userid = getattr(userid, 'user_id', userid)
115 userid = getattr(userid, 'user_id', userid)
114
116
115 user = get_user_or_error(userid)
117 user = get_user_or_error(userid)
116 ips = UserIpMap.query().filter(UserIpMap.user == user).all()
118 ips = UserIpMap.query().filter(UserIpMap.user == user).all()
117 return {
119 return {
118 'server_ip_addr': request.rpc_ip_addr,
120 'server_ip_addr': request.rpc_ip_addr,
119 'user_ips': ips
121 'user_ips': ips
120 }
122 }
121
123
122
124
123 @jsonrpc_method()
125 @jsonrpc_method()
124 def rescan_repos(request, apiuser, remove_obsolete=Optional(False)):
126 def rescan_repos(request, apiuser, remove_obsolete=Optional(False)):
125 """
127 """
126 Triggers a rescan of the specified repositories.
128 Triggers a rescan of the specified repositories.
127
129
128 * If the ``remove_obsolete`` option is set, it also deletes repositories
130 * If the ``remove_obsolete`` option is set, it also deletes repositories
129 that are found in the database but not on the file system, so called
131 that are found in the database but not on the file system, so called
130 "clean zombies".
132 "clean zombies".
131
133
132 This command can only be run using an |authtoken| with admin rights to
134 This command can only be run using an |authtoken| with admin rights to
133 the specified repository.
135 the specified repository.
134
136
135 This command takes the following options:
137 This command takes the following options:
136
138
137 :param apiuser: This is filled automatically from the |authtoken|.
139 :param apiuser: This is filled automatically from the |authtoken|.
138 :type apiuser: AuthUser
140 :type apiuser: AuthUser
139 :param remove_obsolete: Deletes repositories from the database that
141 :param remove_obsolete: Deletes repositories from the database that
140 are not found on the filesystem.
142 are not found on the filesystem.
141 :type remove_obsolete: Optional(``True`` | ``False``)
143 :type remove_obsolete: Optional(``True`` | ``False``)
142
144
143 Example output:
145 Example output:
144
146
145 .. code-block:: bash
147 .. code-block:: bash
146
148
147 id : <id_given_in_input>
149 id : <id_given_in_input>
148 result : {
150 result : {
149 'added': [<added repository name>,...]
151 'added': [<added repository name>,...]
150 'removed': [<removed repository name>,...]
152 'removed': [<removed repository name>,...]
151 }
153 }
152 error : null
154 error : null
153
155
154 Example error output:
156 Example error output:
155
157
156 .. code-block:: bash
158 .. code-block:: bash
157
159
158 id : <id_given_in_input>
160 id : <id_given_in_input>
159 result : null
161 result : null
160 error : {
162 error : {
161 'Error occurred during rescan repositories action'
163 'Error occurred during rescan repositories action'
162 }
164 }
163
165
164 """
166 """
165 if not has_superadmin_permission(apiuser):
167 if not has_superadmin_permission(apiuser):
166 raise JSONRPCForbidden()
168 raise JSONRPCForbidden()
167
169
168 try:
170 try:
169 rm_obsolete = Optional.extract(remove_obsolete)
171 rm_obsolete = Optional.extract(remove_obsolete)
170 added, removed = repo2db_mapper(ScmModel().repo_scan(),
172 added, removed = repo2db_mapper(ScmModel().repo_scan(),
171 remove_obsolete=rm_obsolete)
173 remove_obsolete=rm_obsolete)
172 return {'added': added, 'removed': removed}
174 return {'added': added, 'removed': removed}
173 except Exception:
175 except Exception:
174 log.exception('Failed to run repo rescann')
176 log.exception('Failed to run repo rescann')
175 raise JSONRPCError(
177 raise JSONRPCError(
176 'Error occurred during rescan repositories action'
178 'Error occurred during rescan repositories action'
177 )
179 )
178
180
181
182 @jsonrpc_method()
183 def cleanup_sessions(request, apiuser, older_then=Optional(60)):
184 """
185 Triggers a session cleanup action.
186
187 If the ``older_then`` option is set, only sessions that hasn't been
188 accessed in the given number of days will be removed.
189
190 This command can only be run using an |authtoken| with admin rights to
191 the specified repository.
192
193 This command takes the following options:
194
195 :param apiuser: This is filled automatically from the |authtoken|.
196 :type apiuser: AuthUser
197 :param older_then: Deletes session that hasn't been accessed
198 in given number of days.
199 :type older_then: Optional(int)
200
201 Example output:
202
203 .. code-block:: bash
204
205 id : <id_given_in_input>
206 result: {
207 "backend": "<type of backend>",
208 "sessions_removed": <number_of_removed_sessions>
209 }
210 error : null
211
212 Example error output:
213
214 .. code-block:: bash
215
216 id : <id_given_in_input>
217 result : null
218 error : {
219 'Error occurred during session cleanup'
220 }
221
222 """
223 if not has_superadmin_permission(apiuser):
224 raise JSONRPCForbidden()
225
226 older_then = Optional.extract(older_then)
227 older_than_seconds = 60 * 60 * 24 * older_then
228
229 config = system_info.rhodecode_config().get_value()['value']['config']
230 session_model = user_sessions.get_session_handler(
231 config.get('beaker.session.type', 'memory'))(config)
232
233 backend = session_model.SESSION_TYPE
234 try:
235 cleaned = session_model.clean_sessions(
236 older_than_seconds=older_than_seconds)
237 return {'sessions_removed': cleaned, 'backend': backend}
238 except user_sessions.CleanupCommand as msg:
239 return {'cleanup_command': msg.message, 'backend': backend}
240 except Exception as e:
241 log.exception('Failed session cleanup')
242 raise JSONRPCError(
243 'Error occurred during session cleanup'
244 )
@@ -1,174 +1,181 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2017-2017 RhodeCode GmbH
3 # Copyright (C) 2017-2017 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 import os
21 import os
22 import time
22 import time
23 import datetime
23 import datetime
24 import dateutil
24 import dateutil
25 from rhodecode.model.db import DbSession, Session
25 from rhodecode.model.db import DbSession, Session
26
26
27
27
28 class CleanupCommand(Exception):
28 class CleanupCommand(Exception):
29 pass
29 pass
30
30
31
31
32 class BaseAuthSessions(object):
32 class BaseAuthSessions(object):
33 SESSION_TYPE = None
33 SESSION_TYPE = None
34 NOT_AVAILABLE = 'NOT AVAILABLE'
34 NOT_AVAILABLE = 'NOT AVAILABLE'
35
35
36 def __init__(self, config):
36 def __init__(self, config):
37 session_conf = {}
37 session_conf = {}
38 for k, v in config.items():
38 for k, v in config.items():
39 if k.startswith('beaker.session'):
39 if k.startswith('beaker.session'):
40 session_conf[k] = v
40 session_conf[k] = v
41 self.config = session_conf
41 self.config = session_conf
42
42
43 def get_count(self):
43 def get_count(self):
44 raise NotImplementedError
44 raise NotImplementedError
45
45
46 def get_expired_count(self, older_than_seconds=None):
46 def get_expired_count(self, older_than_seconds=None):
47 raise NotImplementedError
47 raise NotImplementedError
48
48
49 def clean_sessions(self, older_than_seconds=None):
49 def clean_sessions(self, older_than_seconds=None):
50 raise NotImplementedError
50 raise NotImplementedError
51
51
52 def _seconds_to_date(self, seconds):
52 def _seconds_to_date(self, seconds):
53 return datetime.datetime.utcnow() - dateutil.relativedelta.relativedelta(
53 return datetime.datetime.utcnow() - dateutil.relativedelta.relativedelta(
54 seconds=seconds)
54 seconds=seconds)
55
55
56
56
57 class DbAuthSessions(BaseAuthSessions):
57 class DbAuthSessions(BaseAuthSessions):
58 SESSION_TYPE = 'ext:database'
58 SESSION_TYPE = 'ext:database'
59
59
60 def get_count(self):
60 def get_count(self):
61 return DbSession.query().count()
61 return DbSession.query().count()
62
62
63 def get_expired_count(self, older_than_seconds=None):
63 def get_expired_count(self, older_than_seconds=None):
64 expiry_date = self._seconds_to_date(older_than_seconds)
64 expiry_date = self._seconds_to_date(older_than_seconds)
65 return DbSession.query().filter(DbSession.accessed < expiry_date).count()
65 return DbSession.query().filter(DbSession.accessed < expiry_date).count()
66
66
67 def clean_sessions(self, older_than_seconds=None):
67 def clean_sessions(self, older_than_seconds=None):
68 expiry_date = self._seconds_to_date(older_than_seconds)
68 expiry_date = self._seconds_to_date(older_than_seconds)
69 to_remove = DbSession.query().filter(DbSession.accessed < expiry_date).count()
69 DbSession.query().filter(DbSession.accessed < expiry_date).delete()
70 DbSession.query().filter(DbSession.accessed < expiry_date).delete()
70 Session().commit()
71 Session().commit()
72 return to_remove
71
73
72
74
73 class FileAuthSessions(BaseAuthSessions):
75 class FileAuthSessions(BaseAuthSessions):
74 SESSION_TYPE = 'file sessions'
76 SESSION_TYPE = 'file sessions'
75
77
76 def _get_sessions_dir(self):
78 def _get_sessions_dir(self):
77 data_dir = self.config.get('beaker.session.data_dir')
79 data_dir = self.config.get('beaker.session.data_dir')
78 return data_dir
80 return data_dir
79
81
80 def _count_on_filesystem(self, path, older_than=0, callback=None):
82 def _count_on_filesystem(self, path, older_than=0, callback=None):
81 value = dict(percent=0, used=0, total=0, items=0, path=path, text='')
83 value = dict(percent=0, used=0, total=0, items=0, callbacks=0,
84 path=path, text='')
82 items_count = 0
85 items_count = 0
83 used = 0
86 used = 0
87 callbacks = 0
84 cur_time = time.time()
88 cur_time = time.time()
85 for root, dirs, files in os.walk(path):
89 for root, dirs, files in os.walk(path):
86 for f in files:
90 for f in files:
87 final_path = os.path.join(root, f)
91 final_path = os.path.join(root, f)
88 try:
92 try:
89 mtime = os.stat(final_path).st_mtime
93 mtime = os.stat(final_path).st_mtime
90 if (cur_time - mtime) > older_than:
94 if (cur_time - mtime) > older_than:
91 items_count += 1
95 items_count += 1
92 if callback:
96 if callback:
93 callback_res = callback(final_path)
97 callback_res = callback(final_path)
98 callbacks += 1
94 else:
99 else:
95 used += os.path.getsize(final_path)
100 used += os.path.getsize(final_path)
96 except OSError:
101 except OSError:
97 pass
102 pass
98 value.update({
103 value.update({
99 'percent': 100,
104 'percent': 100,
100 'used': used,
105 'used': used,
101 'total': used,
106 'total': used,
102 'items': items_count
107 'items': items_count,
108 'callbacks': callbacks
103 })
109 })
104 return value
110 return value
105
111
106 def get_count(self):
112 def get_count(self):
107 try:
113 try:
108 sessions_dir = self._get_sessions_dir()
114 sessions_dir = self._get_sessions_dir()
109 items_count = self._count_on_filesystem(sessions_dir)['items']
115 items_count = self._count_on_filesystem(sessions_dir)['items']
110 except Exception:
116 except Exception:
111 items_count = self.NOT_AVAILABLE
117 items_count = self.NOT_AVAILABLE
112 return items_count
118 return items_count
113
119
114 def get_expired_count(self, older_than_seconds=0):
120 def get_expired_count(self, older_than_seconds=0):
115 try:
121 try:
116 sessions_dir = self._get_sessions_dir()
122 sessions_dir = self._get_sessions_dir()
117 items_count = self._count_on_filesystem(
123 items_count = self._count_on_filesystem(
118 sessions_dir, older_than=older_than_seconds)['items']
124 sessions_dir, older_than=older_than_seconds)['items']
119 except Exception:
125 except Exception:
120 items_count = self.NOT_AVAILABLE
126 items_count = self.NOT_AVAILABLE
121 return items_count
127 return items_count
122
128
123 def clean_sessions(self, older_than_seconds=0):
129 def clean_sessions(self, older_than_seconds=0):
124 # find . -mtime +60 -exec rm {} \;
130 # find . -mtime +60 -exec rm {} \;
125
131
126 sessions_dir = self._get_sessions_dir()
132 sessions_dir = self._get_sessions_dir()
127
133
128 def remove_item(path):
134 def remove_item(path):
129 os.remove(path)
135 os.remove(path)
130
136
131 return self._count_on_filesystem(
137 stats = self._count_on_filesystem(
132 sessions_dir, older_than=older_than_seconds,
138 sessions_dir, older_than=older_than_seconds,
133 callback=remove_item)['items']
139 callback=remove_item)
140 return stats['callbacks']
134
141
135
142
136 class MemcachedAuthSessions(BaseAuthSessions):
143 class MemcachedAuthSessions(BaseAuthSessions):
137 SESSION_TYPE = 'ext:memcached'
144 SESSION_TYPE = 'ext:memcached'
138
145
139 def get_count(self):
146 def get_count(self):
140 return self.NOT_AVAILABLE
147 return self.NOT_AVAILABLE
141
148
142 def get_expired_count(self, older_than_seconds=None):
149 def get_expired_count(self, older_than_seconds=None):
143 return self.NOT_AVAILABLE
150 return self.NOT_AVAILABLE
144
151
145 def clean_sessions(self, older_than_seconds=None):
152 def clean_sessions(self, older_than_seconds=None):
146 raise CleanupCommand('Cleanup for this session type not yet available')
153 raise CleanupCommand('Cleanup for this session type not yet available')
147
154
148
155
149 class MemoryAuthSessions(BaseAuthSessions):
156 class MemoryAuthSessions(BaseAuthSessions):
150 SESSION_TYPE = 'memory'
157 SESSION_TYPE = 'memory'
151
158
152 def get_count(self):
159 def get_count(self):
153 return self.NOT_AVAILABLE
160 return self.NOT_AVAILABLE
154
161
155 def get_expired_count(self, older_than_seconds=None):
162 def get_expired_count(self, older_than_seconds=None):
156 return self.NOT_AVAILABLE
163 return self.NOT_AVAILABLE
157
164
158 def clean_sessions(self, older_than_seconds=None):
165 def clean_sessions(self, older_than_seconds=None):
159 raise CleanupCommand('Cleanup for this session type not yet available')
166 raise CleanupCommand('Cleanup for this session type not yet available')
160
167
161
168
162 def get_session_handler(session_type):
169 def get_session_handler(session_type):
163 types = {
170 types = {
164 'file': FileAuthSessions,
171 'file': FileAuthSessions,
165 'ext:memcached': MemcachedAuthSessions,
172 'ext:memcached': MemcachedAuthSessions,
166 'ext:database': DbAuthSessions,
173 'ext:database': DbAuthSessions,
167 'memory': MemoryAuthSessions
174 'memory': MemoryAuthSessions
168 }
175 }
169
176
170 try:
177 try:
171 return types[session_type]
178 return types[session_type]
172 except KeyError:
179 except KeyError:
173 raise ValueError(
180 raise ValueError(
174 'This type {} is not supported'.format(session_type))
181 'This type {} is not supported'.format(session_type))
General Comments 0
You need to be logged in to leave comments. Login now