##// END OF EJS Templates
channelstream: use pyramid http exception instead of webob....
marcink -
r2163:a6065ad2 default
parent child Browse files
Show More
@@ -1,176 +1,176 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2017 RhodeCode GmbH
3 # Copyright (C) 2010-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 Channel Stream controller for rhodecode
22 Channel Stream controller for rhodecode
23
23
24 :created_on: Oct 10, 2015
24 :created_on: Oct 10, 2015
25 :author: marcinl
25 :author: marcinl
26 :copyright: (c) 2013-2015 RhodeCode GmbH.
26 :copyright: (c) 2013-2015 RhodeCode GmbH.
27 :license: Commercial License, see LICENSE for more details.
27 :license: Commercial License, see LICENSE for more details.
28 """
28 """
29
29
30 import logging
30 import logging
31 import uuid
31 import uuid
32
32
33 from pyramid.view import view_config
33 from pyramid.view import view_config
34 from webob.exc import HTTPBadRequest, HTTPForbidden, HTTPBadGateway
34 from pyramid.httpexceptions import HTTPBadRequest, HTTPForbidden, HTTPBadGateway
35
35
36 from rhodecode.lib.channelstream import (
36 from rhodecode.lib.channelstream import (
37 channelstream_request,
37 channelstream_request,
38 ChannelstreamConnectionException,
38 ChannelstreamConnectionException,
39 ChannelstreamPermissionException,
39 ChannelstreamPermissionException,
40 check_channel_permissions,
40 check_channel_permissions,
41 get_connection_validators,
41 get_connection_validators,
42 get_user_data,
42 get_user_data,
43 parse_channels_info,
43 parse_channels_info,
44 update_history_from_logs,
44 update_history_from_logs,
45 STATE_PUBLIC_KEYS)
45 STATE_PUBLIC_KEYS)
46 from rhodecode.lib.auth import NotAnonymous
46 from rhodecode.lib.auth import NotAnonymous
47
47
48 log = logging.getLogger(__name__)
48 log = logging.getLogger(__name__)
49
49
50
50
51 class ChannelstreamView(object):
51 class ChannelstreamView(object):
52 def __init__(self, context, request):
52 def __init__(self, context, request):
53 self.context = context
53 self.context = context
54 self.request = request
54 self.request = request
55
55
56 # Some of the decorators rely on this attribute to be present
56 # Some of the decorators rely on this attribute to be present
57 # on the class of the decorated method.
57 # on the class of the decorated method.
58 self._rhodecode_user = request.user
58 self._rhodecode_user = request.user
59 registry = request.registry
59 registry = request.registry
60 self.channelstream_config = registry.rhodecode_plugins['channelstream']
60 self.channelstream_config = registry.rhodecode_plugins['channelstream']
61 if not self.channelstream_config.get('enabled'):
61 if not self.channelstream_config.get('enabled'):
62 log.error('Channelstream plugin is disabled')
62 log.error('Channelstream plugin is disabled')
63 raise HTTPBadRequest()
63 raise HTTPBadRequest()
64
64
65 @NotAnonymous()
65 @NotAnonymous()
66 @view_config(route_name='channelstream_connect', renderer='json')
66 @view_config(route_name='channelstream_connect', renderer='json')
67 def connect(self):
67 def connect(self):
68 """ handle authorization of users trying to connect """
68 """ handle authorization of users trying to connect """
69 try:
69 try:
70 json_body = self.request.json_body
70 json_body = self.request.json_body
71 except Exception:
71 except Exception:
72 log.exception('Failed to decode json from request')
72 log.exception('Failed to decode json from request')
73 raise HTTPBadRequest()
73 raise HTTPBadRequest()
74
74
75 try:
75 try:
76 channels = check_channel_permissions(
76 channels = check_channel_permissions(
77 json_body.get('channels'),
77 json_body.get('channels'),
78 get_connection_validators(self.request.registry))
78 get_connection_validators(self.request.registry))
79 except ChannelstreamPermissionException:
79 except ChannelstreamPermissionException:
80 log.error('Incorrect permissions for requested channels')
80 log.error('Incorrect permissions for requested channels')
81 raise HTTPForbidden()
81 raise HTTPForbidden()
82
82
83 user = self._rhodecode_user
83 user = self._rhodecode_user
84 if user.user_id:
84 if user.user_id:
85 user_data = get_user_data(user.user_id)
85 user_data = get_user_data(user.user_id)
86 else:
86 else:
87 user_data = {
87 user_data = {
88 'id': None,
88 'id': None,
89 'username': None,
89 'username': None,
90 'first_name': None,
90 'first_name': None,
91 'last_name': None,
91 'last_name': None,
92 'icon_link': None,
92 'icon_link': None,
93 'display_name': None,
93 'display_name': None,
94 'display_link': None,
94 'display_link': None,
95 }
95 }
96 user_data['permissions'] = self._rhodecode_user.permissions_safe
96 user_data['permissions'] = self._rhodecode_user.permissions_safe
97 payload = {
97 payload = {
98 'username': user.username,
98 'username': user.username,
99 'user_state': user_data,
99 'user_state': user_data,
100 'conn_id': str(uuid.uuid4()),
100 'conn_id': str(uuid.uuid4()),
101 'channels': channels,
101 'channels': channels,
102 'channel_configs': {},
102 'channel_configs': {},
103 'state_public_keys': STATE_PUBLIC_KEYS,
103 'state_public_keys': STATE_PUBLIC_KEYS,
104 'info': {
104 'info': {
105 'exclude_channels': ['broadcast']
105 'exclude_channels': ['broadcast']
106 }
106 }
107 }
107 }
108 filtered_channels = [channel for channel in channels
108 filtered_channels = [channel for channel in channels
109 if channel != 'broadcast']
109 if channel != 'broadcast']
110 for channel in filtered_channels:
110 for channel in filtered_channels:
111 payload['channel_configs'][channel] = {
111 payload['channel_configs'][channel] = {
112 'notify_presence': True,
112 'notify_presence': True,
113 'history_size': 100,
113 'history_size': 100,
114 'store_history': True,
114 'store_history': True,
115 'broadcast_presence_with_user_lists': True
115 'broadcast_presence_with_user_lists': True
116 }
116 }
117 # connect user to server
117 # connect user to server
118 try:
118 try:
119 connect_result = channelstream_request(self.channelstream_config,
119 connect_result = channelstream_request(self.channelstream_config,
120 payload, '/connect')
120 payload, '/connect')
121 except ChannelstreamConnectionException:
121 except ChannelstreamConnectionException:
122 log.exception('Channelstream service is down')
122 log.exception('Channelstream service is down')
123 return HTTPBadGateway()
123 return HTTPBadGateway()
124
124
125 connect_result['channels'] = channels
125 connect_result['channels'] = channels
126 connect_result['channels_info'] = parse_channels_info(
126 connect_result['channels_info'] = parse_channels_info(
127 connect_result['channels_info'],
127 connect_result['channels_info'],
128 include_channel_info=filtered_channels)
128 include_channel_info=filtered_channels)
129 update_history_from_logs(self.channelstream_config,
129 update_history_from_logs(self.channelstream_config,
130 filtered_channels, connect_result)
130 filtered_channels, connect_result)
131 return connect_result
131 return connect_result
132
132
133 @NotAnonymous()
133 @NotAnonymous()
134 @view_config(route_name='channelstream_subscribe', renderer='json')
134 @view_config(route_name='channelstream_subscribe', renderer='json')
135 def subscribe(self):
135 def subscribe(self):
136 """ can be used to subscribe specific connection to other channels """
136 """ can be used to subscribe specific connection to other channels """
137 try:
137 try:
138 json_body = self.request.json_body
138 json_body = self.request.json_body
139 except Exception:
139 except Exception:
140 log.exception('Failed to decode json from request')
140 log.exception('Failed to decode json from request')
141 raise HTTPBadRequest()
141 raise HTTPBadRequest()
142 try:
142 try:
143 channels = check_channel_permissions(
143 channels = check_channel_permissions(
144 json_body.get('channels'),
144 json_body.get('channels'),
145 get_connection_validators(self.request.registry))
145 get_connection_validators(self.request.registry))
146 except ChannelstreamPermissionException:
146 except ChannelstreamPermissionException:
147 log.error('Incorrect permissions for requested channels')
147 log.error('Incorrect permissions for requested channels')
148 raise HTTPForbidden()
148 raise HTTPForbidden()
149 payload = {'conn_id': json_body.get('conn_id', ''),
149 payload = {'conn_id': json_body.get('conn_id', ''),
150 'channels': channels,
150 'channels': channels,
151 'channel_configs': {},
151 'channel_configs': {},
152 'info': {
152 'info': {
153 'exclude_channels': ['broadcast']}
153 'exclude_channels': ['broadcast']}
154 }
154 }
155 filtered_channels = [chan for chan in channels if chan != 'broadcast']
155 filtered_channels = [chan for chan in channels if chan != 'broadcast']
156 for channel in filtered_channels:
156 for channel in filtered_channels:
157 payload['channel_configs'][channel] = {
157 payload['channel_configs'][channel] = {
158 'notify_presence': True,
158 'notify_presence': True,
159 'history_size': 100,
159 'history_size': 100,
160 'store_history': True,
160 'store_history': True,
161 'broadcast_presence_with_user_lists': True
161 'broadcast_presence_with_user_lists': True
162 }
162 }
163 try:
163 try:
164 connect_result = channelstream_request(
164 connect_result = channelstream_request(
165 self.channelstream_config, payload, '/subscribe')
165 self.channelstream_config, payload, '/subscribe')
166 except ChannelstreamConnectionException:
166 except ChannelstreamConnectionException:
167 log.exception('Channelstream service is down')
167 log.exception('Channelstream service is down')
168 return HTTPBadGateway()
168 return HTTPBadGateway()
169 # include_channel_info will limit history only to new channel
169 # include_channel_info will limit history only to new channel
170 # to not overwrite histories on other channels in client
170 # to not overwrite histories on other channels in client
171 connect_result['channels_info'] = parse_channels_info(
171 connect_result['channels_info'] = parse_channels_info(
172 connect_result['channels_info'],
172 connect_result['channels_info'],
173 include_channel_info=filtered_channels)
173 include_channel_info=filtered_channels)
174 update_history_from_logs(self.channelstream_config,
174 update_history_from_logs(self.channelstream_config,
175 filtered_channels, connect_result)
175 filtered_channels, connect_result)
176 return connect_result
176 return connect_result
General Comments 0
You need to be logged in to leave comments. Login now