##// END OF EJS Templates
audit-logger: store some user details on we have proper object of auth-user.
marcink -
r1701:eddaabf9 default
parent child Browse files
Show More
@@ -1,144 +1,147 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 logging
21 import logging
22 import datetime
22 import datetime
23
23
24 from rhodecode.model import meta
24 from rhodecode.model import meta
25 from rhodecode.model.db import User, UserLog
25 from rhodecode.model.db import User, UserLog
26
26
27
27
28 log = logging.getLogger(__name__)
28 log = logging.getLogger(__name__)
29
29
30
30
31 ACTIONS = {
31 ACTIONS = {
32 'user.login.success': {},
32 'user.login.success': {},
33 'user.login.failure': {},
33 'user.login.failure': {},
34 'user.logout': {},
34 'user.logout': {},
35 'user.password.reset_request': {},
35 'user.password.reset_request': {},
36
36
37 'repo.add': {},
37 'repo.add': {},
38 'repo.edit': {},
38 'repo.edit': {},
39 'repo.commit.strip': {}
39 'repo.commit.strip': {}
40 }
40 }
41
41
42
42
43 class UserWrap(object):
43 class UserWrap(object):
44 """
44 """
45 Fake object used to imitate AuthUser
45 Fake object used to imitate AuthUser
46 """
46 """
47
47
48 def __init__(self, user_id=None, username=None, ip_addr=None):
48 def __init__(self, user_id=None, username=None, ip_addr=None):
49 self.user_id = user_id
49 self.user_id = user_id
50 self.username = username
50 self.username = username
51 self.ip_addr = ip_addr
51 self.ip_addr = ip_addr
52
52
53
53
54 def _store_log(action_name, action_data, user_id, username, user_data,
54 def _store_log(action_name, action_data, user_id, username, user_data,
55 ip_address, repository_id, repository_name):
55 ip_address, repository_id, repository_name):
56 user_log = UserLog()
56 user_log = UserLog()
57 user_log.version = UserLog.VERSION_2
57 user_log.version = UserLog.VERSION_2
58
58
59 user_log.action = action_name
59 user_log.action = action_name
60 user_log.action_data = action_data
60 user_log.action_data = action_data
61
61
62 user_log.user_ip = ip_address
62 user_log.user_ip = ip_address
63
63
64 user_log.user_id = user_id
64 user_log.user_id = user_id
65 user_log.username = username
65 user_log.username = username
66 user_log.user_data = user_data
66 user_log.user_data = user_data
67
67
68 user_log.repository_id = repository_id
68 user_log.repository_id = repository_id
69 user_log.repository_name = repository_name
69 user_log.repository_name = repository_name
70
70
71 user_log.action_date = datetime.datetime.now()
71 user_log.action_date = datetime.datetime.now()
72
72
73 log.info('AUDIT: Logging action: `%s` by user:id:%s[%s] ip:%s',
73 log.info('AUDIT: Logging action: `%s` by user:id:%s[%s] ip:%s',
74 action_name, user_id, username, ip_address)
74 action_name, user_id, username, ip_address)
75
75
76 return user_log
76 return user_log
77
77
78
78
79 def store(
79 def store(
80 action, user, action_data=None, user_data=None, ip_addr=None,
80 action, user, action_data=None, user_data=None, ip_addr=None,
81 repo=None, sa_session=None, commit=False):
81 repo=None, sa_session=None, commit=False):
82 """
82 """
83 Audit logger for various actions made by users, typically this results in a call such::
83 Audit logger for various actions made by users, typically this results in a call such::
84
84
85 from rhodecode.lib import audit_logger
85 from rhodecode.lib import audit_logger
86
86
87 audit_logger.store(action='repo.edit', user=self._rhodecode_user)
87 audit_logger.store(action='repo.edit', user=self._rhodecode_user)
88 audit_logger.store(action='repo.delete', user=audit_logger.UserWrap(username='itried-to-login', ip_addr='8.8.8.8'))
88 audit_logger.store(action='repo.delete', user=audit_logger.UserWrap(username='itried-to-login', ip_addr='8.8.8.8'))
89
89
90 # without an user ?
90 # without an user ?
91 audit_user = audit_logger.UserWrap(
91 audit_user = audit_logger.UserWrap(
92 username=self.request.params.get('username'),
92 username=self.request.params.get('username'),
93 ip_addr=self.request.remote_addr)
93 ip_addr=self.request.remote_addr)
94 audit_logger.store(action='user.login.failure', user=audit_user)
94 audit_logger.store(action='user.login.failure', user=audit_user)
95 """
95 """
96 from rhodecode.lib.utils2 import safe_unicode
96 from rhodecode.lib.utils2 import safe_unicode
97 from rhodecode.lib.auth import AuthUser
97 from rhodecode.lib.auth import AuthUser
98
98
99 if action not in ACTIONS:
99 if action not in ACTIONS:
100 raise ValueError('Action `{}` not in valid actions'.format(action))
100 raise ValueError('Action `{}` not in valid actions'.format(action))
101
101
102 if not sa_session:
102 if not sa_session:
103 sa_session = meta.Session()
103 sa_session = meta.Session()
104
104
105 try:
105 try:
106 username = getattr(user, 'username', None)
106 username = getattr(user, 'username', None)
107 if not username:
107 if not username:
108 pass
108 pass
109
109
110 user_id = getattr(user, 'user_id', None)
110 user_id = getattr(user, 'user_id', None)
111 if not user_id:
111 if not user_id:
112 # maybe we have username ? Try to figure user_id from username
112 # maybe we have username ? Try to figure user_id from username
113 if username:
113 if username:
114 user_id = getattr(
114 user_id = getattr(
115 User.get_by_username(username), 'user_id', None)
115 User.get_by_username(username), 'user_id', None)
116
116
117 ip_addr = ip_addr or getattr(user, 'ip_addr', None)
117 ip_addr = ip_addr or getattr(user, 'ip_addr', None)
118 if not ip_addr:
118 if not ip_addr:
119 pass
119 pass
120
120
121 if not user_data:
121 if not user_data:
122 # try to get this from the auth user
122 # try to get this from the auth user
123 if isinstance(user, AuthUser):
123 if isinstance(user, AuthUser):
124 user_data = {}
124 user_data = {
125 'username': user.username,
126 'email': user.email,
127 }
125
128
126 repository_id = getattr(repo, 'repo_id', None)
129 repository_id = getattr(repo, 'repo_id', None)
127 repository_name = getattr(repo, 'repo_name', None)
130 repository_name = getattr(repo, 'repo_name', None)
128
131
129 user_log = _store_log(
132 user_log = _store_log(
130 action_name=safe_unicode(action),
133 action_name=safe_unicode(action),
131 action_data=action_data or {},
134 action_data=action_data or {},
132 user_id=user_id,
135 user_id=user_id,
133 username=username,
136 username=username,
134 user_data=user_data or {},
137 user_data=user_data or {},
135 ip_address=safe_unicode(ip_addr),
138 ip_address=safe_unicode(ip_addr),
136 repository_id=repository_id,
139 repository_id=repository_id,
137 repository_name=repository_name
140 repository_name=repository_name
138 )
141 )
139 sa_session.add(user_log)
142 sa_session.add(user_log)
140 if commit:
143 if commit:
141 sa_session.commit()
144 sa_session.commit()
142
145
143 except Exception:
146 except Exception:
144 log.exception('AUDIT: failed to store audit log')
147 log.exception('AUDIT: failed to store audit log')
General Comments 0
You need to be logged in to leave comments. Login now