##// END OF EJS Templates
user-sessions: fix other backend expired count, and fixed some helper text.
marcink -
r1298:db672357 default
parent child Browse files
Show More
@@ -1,125 +1,125 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 datetime
21 import datetime
22 import dateutil
22 import dateutil
23 from rhodecode.model.db import DbSession, Session
23 from rhodecode.model.db import DbSession, Session
24
24
25
25
26 class CleanupCommand(Exception):
26 class CleanupCommand(Exception):
27 pass
27 pass
28
28
29
29
30 class BaseAuthSessions(object):
30 class BaseAuthSessions(object):
31 SESSION_TYPE = None
31 SESSION_TYPE = None
32
32
33 def __init__(self, config):
33 def __init__(self, config):
34 session_conf = {}
34 session_conf = {}
35 for k, v in config.items():
35 for k, v in config.items():
36 if k.startswith('beaker.session'):
36 if k.startswith('beaker.session'):
37 session_conf[k] = v
37 session_conf[k] = v
38 self.config = session_conf
38 self.config = session_conf
39
39
40 def get_count(self):
40 def get_count(self):
41 raise NotImplementedError
41 raise NotImplementedError
42
42
43 def get_expired_count(self):
43 def get_expired_count(self, older_than_seconds=None):
44 raise NotImplementedError
44 raise NotImplementedError
45
45
46 def clean_sessions(self, older_than_seconds=None):
46 def clean_sessions(self, older_than_seconds=None):
47 raise NotImplementedError
47 raise NotImplementedError
48
48
49 def _seconds_to_date(self, seconds):
49 def _seconds_to_date(self, seconds):
50 return datetime.datetime.utcnow() - dateutil.relativedelta.relativedelta(
50 return datetime.datetime.utcnow() - dateutil.relativedelta.relativedelta(
51 seconds=seconds)
51 seconds=seconds)
52
52
53
53
54 class DbAuthSessions(BaseAuthSessions):
54 class DbAuthSessions(BaseAuthSessions):
55 SESSION_TYPE = 'ext:database'
55 SESSION_TYPE = 'ext:database'
56
56
57 def get_count(self):
57 def get_count(self):
58 return DbSession.query().count()
58 return DbSession.query().count()
59
59
60 def get_expired_count(self, older_than_seconds=None):
60 def get_expired_count(self, older_than_seconds=None):
61 expiry_date = self._seconds_to_date(older_than_seconds)
61 expiry_date = self._seconds_to_date(older_than_seconds)
62 return DbSession.query().filter(DbSession.accessed < expiry_date).count()
62 return DbSession.query().filter(DbSession.accessed < expiry_date).count()
63
63
64 def clean_sessions(self, older_than_seconds=None):
64 def clean_sessions(self, older_than_seconds=None):
65 expiry_date = self._seconds_to_date(older_than_seconds)
65 expiry_date = self._seconds_to_date(older_than_seconds)
66 DbSession.query().filter(DbSession.accessed < expiry_date).delete()
66 DbSession.query().filter(DbSession.accessed < expiry_date).delete()
67 Session().commit()
67 Session().commit()
68
68
69
69
70 class FileAuthSessions(BaseAuthSessions):
70 class FileAuthSessions(BaseAuthSessions):
71 SESSION_TYPE = 'file sessions'
71 SESSION_TYPE = 'file sessions'
72
72
73 def get_count(self):
73 def get_count(self):
74 return 'NOT AVAILABLE'
74 return 'NOT AVAILABLE'
75
75
76 def get_expired_count(self):
76 def get_expired_count(self, older_than_seconds=None):
77 return self.get_count()
77 return self.get_count()
78
78
79 def clean_sessions(self, older_than_seconds=None):
79 def clean_sessions(self, older_than_seconds=None):
80 data_dir = self.config.get('beaker.session.data_dir')
80 data_dir = self.config.get('beaker.session.data_dir')
81 raise CleanupCommand(
81 raise CleanupCommand(
82 'Please execute this command: '
82 'Please execute this command: '
83 '`find . -mtime +60 -exec rm {{}} \;` inside {} directory'.format(
83 '`find . -mtime +60 -exec rm {{}} \;` inside {} directory'.format(
84 data_dir))
84 data_dir))
85
85
86
86
87 class MemcachedAuthSessions(BaseAuthSessions):
87 class MemcachedAuthSessions(BaseAuthSessions):
88 SESSION_TYPE = 'ext:memcached'
88 SESSION_TYPE = 'ext:memcached'
89
89
90 def get_count(self):
90 def get_count(self):
91 return 'NOT AVAILABLE'
91 return 'NOT AVAILABLE'
92
92
93 def get_expired_count(self):
93 def get_expired_count(self, older_than_seconds=None):
94 return self.get_count()
94 return self.get_count()
95
95
96 def clean_sessions(self, older_than_seconds=None):
96 def clean_sessions(self, older_than_seconds=None):
97 raise CleanupCommand('Cleanup for this session type not yet available')
97 raise CleanupCommand('Cleanup for this session type not yet available')
98
98
99
99
100 class MemoryAuthSessions(BaseAuthSessions):
100 class MemoryAuthSessions(BaseAuthSessions):
101 SESSION_TYPE = 'memory'
101 SESSION_TYPE = 'memory'
102
102
103 def get_count(self):
103 def get_count(self):
104 return 'NOT AVAILABLE'
104 return 'NOT AVAILABLE'
105
105
106 def get_expired_count(self):
106 def get_expired_count(self, older_than_seconds=None):
107 return self.get_count()
107 return self.get_count()
108
108
109 def clean_sessions(self, older_than_seconds=None):
109 def clean_sessions(self, older_than_seconds=None):
110 raise CleanupCommand('Cleanup for this session type not yet available')
110 raise CleanupCommand('Cleanup for this session type not yet available')
111
111
112
112
113 def get_session_handler(session_type):
113 def get_session_handler(session_type):
114 types = {
114 types = {
115 'file': FileAuthSessions,
115 'file': FileAuthSessions,
116 'ext:memcached': MemcachedAuthSessions,
116 'ext:memcached': MemcachedAuthSessions,
117 'ext:database': DbAuthSessions,
117 'ext:database': DbAuthSessions,
118 'memory': MemoryAuthSessions
118 'memory': MemoryAuthSessions
119 }
119 }
120
120
121 try:
121 try:
122 return types[session_type]
122 return types[session_type]
123 except KeyError:
123 except KeyError:
124 raise ValueError(
124 raise ValueError(
125 'This type {} is not supported'.format(session_type))
125 'This type {} is not supported'.format(session_type))
@@ -1,60 +1,62 b''
1 <div class="panel panel-default">
1 <div class="panel panel-default">
2 <div class="panel-heading">
2 <div class="panel-heading">
3 <h3 class="panel-title">${_('User Sessions Configuration')}</h3>
3 <h3 class="panel-title">${_('User Sessions Configuration')}</h3>
4 </div>
4 </div>
5 <div class="panel-body">
5 <div class="panel-body">
6 <%
6 <%
7 elems = [
7 elems = [
8 (_('Session type'), c.session_model.SESSION_TYPE, ''),
8 (_('Session type'), c.session_model.SESSION_TYPE, ''),
9 (_('Session expiration period'), '{} seconds'.format(c.session_conf.get('beaker.session.timeout', 0)), ''),
9 (_('Session expiration period'), '{} seconds'.format(c.session_conf.get('beaker.session.timeout', 0)), ''),
10
10
11 (_('Total sessions'), c.session_count, ''),
11 (_('Total sessions'), c.session_count, ''),
12 (_('Expired sessions ({} days)').format(c.cleanup_older_days ), c.session_expired_count, ''),
12 (_('Expired sessions ({} days)').format(c.cleanup_older_days ), c.session_expired_count, ''),
13
13
14 ]
14 ]
15 %>
15 %>
16 <dl class="dl-horizontal settings">
16 <dl class="dl-horizontal settings">
17 %for dt, dd, tt in elems:
17 %for dt, dd, tt in elems:
18 <dt>${dt}:</dt>
18 <dt>${dt}:</dt>
19 <dd title="${tt}">${dd}</dd>
19 <dd title="${tt}">${dd}</dd>
20 %endfor
20 %endfor
21 </dl>
21 </dl>
22 </div>
22 </div>
23 </div>
23 </div>
24
24
25
25
26 <div class="panel panel-warning">
26 <div class="panel panel-warning">
27 <div class="panel-heading">
27 <div class="panel-heading">
28 <h3 class="panel-title">${_('Cleanup Old Sessions')}</h3>
28 <h3 class="panel-title">${_('Cleanup Old Sessions')}</h3>
29 </div>
29 </div>
30 <div class="panel-body">
30 <div class="panel-body">
31 ${h.secure_form(h.url('admin_settings_sessions_cleanup'), method='post')}
31 ${h.secure_form(h.url('admin_settings_sessions_cleanup'), method='post')}
32
32
33 <div style="margin: 0 0 20px 0" class="fake-space">
33 <p>
34 ${_('Cleanup all sessions that were not active during choosen time frame')} <br/>
34 ${_('Cleanup user sessions that were not active during chosen time frame.')} <br/>
35 ${_('Picking All will log-out all users in the system, and each user will be required to log in again.')}
35 ${_('After performing this action users whose session will be removed will be required to log in again.')} <br/>
36 </div>
36 <strong>${_('Picking `All` will log-out you, and all users in the system.')}</strong>
37 </p>
38
39 <script type="text/javascript">
40 $(document).ready(function() {
41 $('#expire_days').select2({
42 containerCssClass: 'drop-menu',
43 dropdownCssClass: 'drop-menu-dropdown',
44 dropdownAutoWidth: true,
45 minimumResultsForSearch: -1
46 });
47 });
48 </script>
37 <select id="expire_days" name="expire_days">
49 <select id="expire_days" name="expire_days">
38 % for n in [60, 90, 30, 7, 0]:
50 % for n in [60, 90, 30, 7, 0]:
39 <option value="${n}">${'{} days'.format(n) if n != 0 else 'All'}</option>
51 <option value="${n}">${'{} days'.format(n) if n != 0 else 'All'}</option>
40 % endfor
52 % endfor
41 </select>
53 </select>
42 <button class="btn btn-small" type="submit"
54 <button class="btn btn-small" type="submit"
43 onclick="return confirm('${_('Confirm to cleanup user sessions')}');">
55 onclick="return confirm('${_('Confirm to cleanup user sessions')}');">
44 ${_('Cleanup sessions')}
56 ${_('Cleanup sessions')}
45 </button>
57 </button>
46 ${h.end_form()}
58 ${h.end_form()}
47 </div>
59 </div>
48 </div>
60 </div>
49
61
50
62
51 <script type="text/javascript">
52 $(document).ready(function() {
53 $('#expire_days').select2({
54 containerCssClass: 'drop-menu',
55 dropdownCssClass: 'drop-menu-dropdown',
56 dropdownAutoWidth: true,
57 minimumResultsForSearch: -1
58 });
59 });
60 </script> No newline at end of file
General Comments 0
You need to be logged in to leave comments. Login now