forked from zatosource/zato
/
__init__.py
126 lines (90 loc) · 4.06 KB
/
__init__.py
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
# -*- coding: utf-8 -*-
"""
Copyright (C) 2010 Dariusz Suchojad <dsuch at zato.io>
Licensed under LGPLv3, see LICENSE.txt for terms and conditions.
"""
from __future__ import absolute_import, division, print_function, unicode_literals
# stdlib
import logging
from contextlib import closing
from traceback import format_exc
# Zato
from zato.common import SECRET_SHADOW, zato_namespace, ZATO_NONE
from zato.common.broker_message import MESSAGE_TYPE
from zato.common.util import replace_private_key
from zato.server.service import Service
success_code = 0
success = '<error_code>{}</error_code>'.format(success_code)
logger = logging.getLogger('zato_admin')
class AdminService(Service):
""" A Zato admin service, part of the API.
"""
def __init__(self):
super(AdminService, self).__init__()
def before_handle(self):
if logger.isEnabledFor(logging.INFO):
request = dict(self.request.input)
for k, v in request.items():
v = replace_private_key(v)
if 'password' in k:
request[k] = SECRET_SHADOW
logger.info('cid:[%s], name:[%s], SIO request:[%s]', self.cid, self.name, request)
def handle(self, *args, **kwargs):
raise NotImplementedError('Should be overridden by subclasses')
def after_handle(self):
payload = self.response.payload
response = replace_private_key(payload if isinstance(payload, basestring) else payload.getvalue())
logger.info('cid:[{}], name:[{}], response:[{}]'.format(self.cid, self.name, response))
def get_data(self, *args, **kwargs):
raise NotImplementedError('Should be overridden by subclasses')
class AdminSIO(object):
namespace = zato_namespace
class Ping(AdminService):
class SimpleIO(AdminSIO):
output_required = ('pong',)
response_elem = 'zato_ping_response'
def handle(self):
self.response.payload.pong = 'zato'
class Ping2(Ping):
class SimpleIO(Ping.SimpleIO):
response_elem = 'zato_ping2_response'
class ChangePasswordBase(AdminService):
""" A base class for handling the changing of any of the ODB passwords.
"""
# Subclasses may wish to set it to False to special-case what they need to deal with
password_required = True
class SimpleIO(AdminSIO):
input_required = ('id', 'password1', 'password2')
def _handle(self, class_, auth_func, action, name_func=None, msg_type=MESSAGE_TYPE.TO_PARALLEL_ALL,
*args, **kwargs):
with closing(self.odb.session()) as session:
password1 = self.request.input.get('password1', '')
password2 = self.request.input.get('password2', '')
try:
if self.password_required:
if not password1:
raise Exception('Password must not be empty')
if not password2:
raise Exception('Password must be repeated')
if password1 != password2:
raise Exception('Passwords need to be the same')
auth = session.query(class_).\
filter(class_.id==self.request.input.id).\
one()
auth_func(auth, password1)
session.add(auth)
session.commit()
if msg_type:
name = name_func(auth) if name_func else auth.name
self.request.input.action = action
self.request.input.name = name
self.request.input.password = auth.password
self.request.input.salt = kwargs.get('salt')
for attr in kwargs.get('publish_instance_attrs', []):
self.request.input[attr] = getattr(auth, attr, ZATO_NONE)
self.broker_client.publish(self.request.input, msg_type=msg_type)
except Exception, e:
msg = 'Could not update the password, e:[{}]'.format(format_exc(e))
self.logger.error(msg)
session.rollback()
raise