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