views.py
183 lines
| 6.8 KiB
| text/x-python
|
PythonLexer
r5088 | # Copyright (C) 2010-2023 RhodeCode GmbH | |||
r1504 | # | |||
# This program is free software: you can redistribute it and/or modify | ||||
# it under the terms of the GNU Affero General Public License, version 3 | ||||
# (only), as published by the Free Software Foundation. | ||||
# | ||||
# This program is distributed in the hope that it will be useful, | ||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
# GNU General Public License for more details. | ||||
# | ||||
# You should have received a copy of the GNU Affero General Public License | ||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. | ||||
# | ||||
# This program is dual-licensed. If you wish to learn more about the | ||||
# RhodeCode Enterprise Edition, including its added features, Support services, | ||||
# and proprietary license terms, please see https://rhodecode.com/licenses/ | ||||
import logging | ||||
import uuid | ||||
r4610 | ||||
r2163 | from pyramid.httpexceptions import HTTPBadRequest, HTTPForbidden, HTTPBadGateway | |||
r1504 | ||||
r2351 | from rhodecode.apps._base import BaseAppView | |||
r1504 | from rhodecode.lib.channelstream import ( | |||
r3169 | channelstream_request, get_channelstream_server_url, | |||
r1504 | ChannelstreamConnectionException, | |||
ChannelstreamPermissionException, | ||||
check_channel_permissions, | ||||
get_connection_validators, | ||||
get_user_data, | ||||
parse_channels_info, | ||||
update_history_from_logs, | ||||
r4479 | USER_STATE_PUBLIC_KEYS) | |||
r2351 | ||||
r1504 | from rhodecode.lib.auth import NotAnonymous | |||
log = logging.getLogger(__name__) | ||||
r2351 | class ChannelstreamView(BaseAppView): | |||
r1504 | ||||
r2351 | def load_default_context(self): | |||
c = self._get_local_tmpl_context() | ||||
self.channelstream_config = \ | ||||
self.request.registry.rhodecode_plugins['channelstream'] | ||||
r1504 | if not self.channelstream_config.get('enabled'): | |||
r4787 | log.warning('Channelstream plugin is disabled') | |||
r1504 | raise HTTPBadRequest() | |||
r2351 | return c | |||
r1504 | @NotAnonymous() | |||
r4610 | def channelstream_connect(self): | |||
r3169 | """ handle authorization of users trying to connect """ | |||
r2351 | self.load_default_context() | |||
r1504 | try: | |||
json_body = self.request.json_body | ||||
except Exception: | ||||
log.exception('Failed to decode json from request') | ||||
raise HTTPBadRequest() | ||||
r2157 | ||||
r1504 | try: | |||
channels = check_channel_permissions( | ||||
json_body.get('channels'), | ||||
get_connection_validators(self.request.registry)) | ||||
except ChannelstreamPermissionException: | ||||
log.error('Incorrect permissions for requested channels') | ||||
raise HTTPForbidden() | ||||
r1782 | user = self._rhodecode_user | |||
r1504 | if user.user_id: | |||
user_data = get_user_data(user.user_id) | ||||
else: | ||||
user_data = { | ||||
'id': None, | ||||
'username': None, | ||||
'first_name': None, | ||||
'last_name': None, | ||||
'icon_link': None, | ||||
'display_name': None, | ||||
'display_link': None, | ||||
} | ||||
r4479 | ||||
#user_data['permissions'] = self._rhodecode_user.permissions_safe | ||||
r1504 | payload = { | |||
'username': user.username, | ||||
'user_state': user_data, | ||||
'conn_id': str(uuid.uuid4()), | ||||
'channels': channels, | ||||
'channel_configs': {}, | ||||
r4479 | 'state_public_keys': USER_STATE_PUBLIC_KEYS, | |||
r1504 | 'info': { | |||
'exclude_channels': ['broadcast'] | ||||
} | ||||
} | ||||
filtered_channels = [channel for channel in channels | ||||
if channel != 'broadcast'] | ||||
for channel in filtered_channels: | ||||
payload['channel_configs'][channel] = { | ||||
'notify_presence': True, | ||||
'history_size': 100, | ||||
'store_history': True, | ||||
'broadcast_presence_with_user_lists': True | ||||
} | ||||
# connect user to server | ||||
r3169 | channelstream_url = get_channelstream_server_url( | |||
self.channelstream_config, '/connect') | ||||
r1504 | try: | |||
r3169 | connect_result = channelstream_request( | |||
self.channelstream_config, payload, '/connect') | ||||
r1504 | except ChannelstreamConnectionException: | |||
r3169 | log.exception( | |||
r5095 | f'Channelstream service at {channelstream_url} is down') | |||
r1504 | return HTTPBadGateway() | |||
r4479 | channel_info = connect_result.get('channels_info') | |||
if not channel_info: | ||||
raise HTTPBadRequest() | ||||
r1504 | connect_result['channels'] = channels | |||
connect_result['channels_info'] = parse_channels_info( | ||||
r4479 | channel_info, include_channel_info=filtered_channels) | |||
r1504 | update_history_from_logs(self.channelstream_config, | |||
filtered_channels, connect_result) | ||||
return connect_result | ||||
@NotAnonymous() | ||||
r4610 | def channelstream_subscribe(self): | |||
r1504 | """ can be used to subscribe specific connection to other channels """ | |||
r2351 | self.load_default_context() | |||
r1504 | try: | |||
json_body = self.request.json_body | ||||
except Exception: | ||||
log.exception('Failed to decode json from request') | ||||
raise HTTPBadRequest() | ||||
try: | ||||
channels = check_channel_permissions( | ||||
json_body.get('channels'), | ||||
get_connection_validators(self.request.registry)) | ||||
except ChannelstreamPermissionException: | ||||
log.error('Incorrect permissions for requested channels') | ||||
raise HTTPForbidden() | ||||
payload = {'conn_id': json_body.get('conn_id', ''), | ||||
'channels': channels, | ||||
'channel_configs': {}, | ||||
'info': { | ||||
'exclude_channels': ['broadcast']} | ||||
} | ||||
filtered_channels = [chan for chan in channels if chan != 'broadcast'] | ||||
for channel in filtered_channels: | ||||
payload['channel_configs'][channel] = { | ||||
'notify_presence': True, | ||||
'history_size': 100, | ||||
'store_history': True, | ||||
'broadcast_presence_with_user_lists': True | ||||
} | ||||
r3169 | ||||
channelstream_url = get_channelstream_server_url( | ||||
self.channelstream_config, '/subscribe') | ||||
r1504 | try: | |||
connect_result = channelstream_request( | ||||
self.channelstream_config, payload, '/subscribe') | ||||
except ChannelstreamConnectionException: | ||||
r3169 | log.exception( | |||
r5095 | f'Channelstream service at {channelstream_url} is down') | |||
r1504 | return HTTPBadGateway() | |||
r4479 | ||||
channel_info = connect_result.get('channels_info') | ||||
if not channel_info: | ||||
raise HTTPBadRequest() | ||||
r1504 | # include_channel_info will limit history only to new channel | |||
# to not overwrite histories on other channels in client | ||||
connect_result['channels_info'] = parse_channels_info( | ||||
r4479 | channel_info, | |||
r1504 | include_channel_info=filtered_channels) | |||
r3169 | update_history_from_logs( | |||
self.channelstream_config, filtered_channels, connect_result) | ||||
r1504 | return connect_result | |||