Fixing up REST api for client access

This commit is contained in:
Adolfo Gómez García 2017-11-10 14:10:26 +01:00
parent de051d99ac
commit cb13ac1617
4 changed files with 59 additions and 87 deletions

View File

@ -36,11 +36,13 @@ from django.utils.translation import ugettext as _
from uds.REST import Handler from uds.REST import Handler
from uds.REST import RequestError from uds.REST import RequestError
from uds.models import UserService, DeployedService, Transport from uds.models import UserService, DeployedService, Transport, ServicesPoolGroup
from uds.core.util.model import processUuid from uds.core.util.model import processUuid
from uds.core.managers.UserServiceManager import UserServiceManager from uds.core.managers import userServiceManager
# from uds.core.managers.UserServiceManager import UserServiceManager
from uds.core.util import log from uds.core.util import log
from uds.core.util.stats import events from uds.core.util.stats import events
from uds.core.ui.images import DEFAULT_THUMB_BASE64
import datetime import datetime
@ -90,32 +92,50 @@ class Connection(Handler):
if t.validForIp(self._request.ip) and t.getType().providesConnetionInfo(): if t.validForIp(self._request.ip) and t.getType().providesConnetionInfo():
trans.append({'id': t.uuid, 'name': t.name}) trans.append({'id': t.uuid, 'name': t.name})
servicePool = svr.deployed_service
services.append({'id': 'A' + svr.uuid, services.append({'id': 'A' + svr.uuid,
'name': svr['name'], 'name': servicePool.name,
'description': servicePool.comments,
'visual_name': servicePool.visual_name,
'group': servicePool.servicesPoolGroup if servicePool.servicesPoolGroup is not None else ServicesPoolGroup.default().as_dict,
'thumb': servicePool.image.thumb64 if servicePool.image is not None else DEFAULT_THUMB_BASE64,
'show_transports': servicePool.show_transports,
'allow_users_remove': servicePool.allow_users_remove,
'maintenance': servicePool.isInMaintenance(),
'not_accesible': not servicePool.isAccessAllowed(),
'to_be_replaced': False, # Manually assigned will not be autoremoved never
'transports': trans, 'transports': trans,
'maintenance': svr.isInMaintenance(),
'in_use': svr.in_use}) 'in_use': svr.in_use})
logger.debug(services) logger.debug(services)
# Now generic user service # Now generic user service
for svr in availServices: for servicePool in availServices:
trans = [] trans = []
for t in svr.transports.all().order_by('priority'): for t in servicePool.transports.all().order_by('priority'):
if t.validForIp(self._request.ip) and t.getType().providesConnetionInfo(): if t.validForIp(self._request.ip) and t.getType().providesConnetionInfo():
trans.append({'id': t.uuid, 'name': t.name}) trans.append({'id': t.uuid, 'name': t.name})
# Locate if user service has any already assigned user service for this # Locate if user service has any already assigned user service for this
ads = UserServiceManager.manager().getExistingAssignationForUser(svr, self._user) ads = userServiceManager().getExistingAssignationForUser(servicePool, self._user)
if ads is None: if ads is None:
in_use = False in_use = False
else: else:
in_use = ads.in_use in_use = ads.in_use
services.append({'id': 'F' + svr.uuid, services.append({'id': 'F' + servicePool.uuid,
'name': svr.name, 'name': servicePool.name,
'description': servicePool.comments,
'visual_name': servicePool.visual_name,
'group': servicePool.servicesPoolGroup if servicePool.servicesPoolGroup is not None else ServicesPoolGroup.default().as_dict,
'thumb': servicePool.image.thumb64 if servicePool.image is not None else DEFAULT_THUMB_BASE64,
'show_transports': servicePool.show_transports,
'allow_users_remove': servicePool.allow_users_remove,
'maintenance': servicePool.isInMaintenance(),
'not_accesible': not servicePool.isAccessAllowed(),
'to_be_replaced': servicePool.toBeReplaced(),
'transports': trans, 'transports': trans,
'maintenance': svr.isInMaintenance(),
'in_use': in_use}) 'in_use': in_use})
logger.debug('Services: {0}'.format(services)) logger.debug('Services: {0}'.format(services))
@ -125,70 +145,18 @@ class Connection(Handler):
return Connection.result(result=services) return Connection.result(result=services)
def connection(self, doNotCheck=False): def connection(self, doNotCheck=False):
kind, idService = self._args[0][0], self._args[0][1:] idService = self._args[0]
idTransport = self._args[1] idTransport = self._args[1]
ip, userService, iads, trans, itrans = userServiceManager().getService(self._user, self._request.ip, idService, idTransport, not doNotCheck)
logger.debug('Type: {}, Service: {}, Transport: {}'.format(kind, idService, idTransport)) ci = {
'username': '',
try: 'password': '',
logger.debug('Kind of service: {0}, idService: {1}'.format(kind, idService)) 'domain': '',
if kind == 'A': # This is an assigned service 'protocol': 'unknown',
ads = UserService.objects.get(uuid=processUuid(idService)) 'ip': ip
else: }
ds = DeployedService.objects.get(uuid=processUuid(idService)) ci.update(itrans.getConnectionInfo(userService, self._user, 'UNKNOWN'))
# We first do a sanity check for this, if the user has access to this service return Connection.result(result=ci)
# If it fails, will raise an exception
ds.validateUser(self._user)
# Now we have to locate an instance of the service, so we can assign it to user.
ads = UserServiceManager.manager().getAssignationForUser(ds, self._user)
if ads.isInMaintenance() is True:
return Connection.result(error='Service in maintenance')
logger.debug('Found service: {0}'.format(ads))
trans = Transport.objects.get(uuid=processUuid(idTransport))
if trans.validForIp(self._request.ip) is False:
return Connection.result(error='Access denied')
# Test if the service is ready
if doNotCheck or ads.isReady():
log.doLog(ads, log.INFO, "User {0} from {1} has initiated access".format(self._user.name, self._request.ip), log.WEB)
# If ready, show transport for this service, if also ready ofc
iads = ads.getInstance()
ip = iads.getIp()
logger.debug('IP: {}'.format(ip))
events.addEvent(ads.deployed_service, events.ET_ACCESS, username=self._user.name, srcip=self._request.ip, dstip=ip, uniqueid=ads.unique_id)
if ip is not None:
itrans = trans.getInstance()
if itrans.providesConnetionInfo() and (doNotCheck or itrans.isAvailableFor(ads, ip)):
ads.setConnectionSource(self._request.ip, 'unknown')
log.doLog(ads, log.INFO, "User service ready, rendering transport", log.WEB)
ci = {
'username': '',
'password': '',
'domain': '',
'protocol': 'unknown',
'ip': ip
}
ci.update(itrans.getConnectionInfo(ads, self._user, 'UNKNOWN'))
UserServiceManager.manager().notifyPreconnect(ads, itrans.processedUser(ads, self._user), itrans.protocol)
return Connection.result(result=ci)
else:
log.doLog(ads, log.WARN, "User service is not accessible by REST (ip {0})".format(ip), log.TRANSPORT)
logger.debug('Transport {} is not accesible for user service {} from {}'.format(trans, ads, self._request.ip))
logger.debug("{}, {}".format(itrans.providesConnetionInfo(), itrans.isAvailableFor(ads, ip)))
else:
logger.debug('Ip not available from user service {0}'.format(ads))
else:
log.doLog(ads, log.WARN, "User {0} from {1} tried to access, but service was not ready".format(self._user.name, self._request.ip), log.WEB)
# Not ready, show message and return to this page in a while
return Connection.result(error='Service not ready')
except Exception as e:
return Connection.result(error=six.text_type(e))
def get(self): def get(self):
''' '''

View File

@ -36,6 +36,7 @@ from uds.core.util.Config import GlobalConfig
from uds.core.util.model import processUuid from uds.core.util.model import processUuid
from uds.models import Authenticator from uds.models import Authenticator
from uds.core.auths.auth import authenticate from uds.core.auths.auth import authenticate
from uds.core import VERSION as UDS_VERSION
from uds.REST import RequestError from uds.REST import RequestError
from uds.REST import Handler from uds.REST import Handler
@ -105,7 +106,7 @@ class Login(Handler):
if user is None: # invalid credentials if user is None: # invalid credentials
raise Exception() raise Exception()
self.genAuthToken(auth.id, user.name, locale, user.is_admin, user.staff_member) self.genAuthToken(auth.id, user.name, locale, user.is_admin, user.staff_member)
return{'result': 'ok', 'token': self.getAuthToken()} return{'result': 'ok', 'token': self.getAuthToken(), 'version': UDS_VERSION }
except: except:
logger.exception('Credentials ') logger.exception('Credentials ')
raise Exception('Invalid Credentials (invalid authenticator)') raise Exception('Invalid Credentials (invalid authenticator)')

View File

@ -22,6 +22,7 @@
{% csrf_token %} {% csrf_token %}
<input id="id_language" type="hidden" name="language" value=""/> <input id="id_language" type="hidden" name="language" value=""/>
<ul class="nav navbar-nav navbar-right"> <ul class="nav navbar-nav navbar-right">
<li><a href="{% url 'ClientDownload' %}"><span class="fa fa-download"></span> {% trans 'UDS Plugin' %}</a></li>
<li><a href="{% url 'uds.web.views.about' %}">{% trans 'About' %}</a></li> <li><a href="{% url 'uds.web.views.about' %}">{% trans 'About' %}</a></li>
<li class="dropdown"> <li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><i class="fa fa-comments-o"></i> {% trans LANGUAGE_INFO.name|capfirst %}<b class="caret"></b></a> <a href="#" class="dropdown-toggle" data-toggle="dropdown"><i class="fa fa-comments-o"></i> {% trans LANGUAGE_INFO.name|capfirst %}<b class="caret"></b></a>
@ -40,7 +41,6 @@
{% if show_prefs and user.id != rootid %} {% if show_prefs and user.id != rootid %}
<li><a href="{% url "uds.web.views.prefs" %}"><span class="fa fa-edit"></span> {% trans 'Preferences' %}</a></li> <li><a href="{% url "uds.web.views.prefs" %}"><span class="fa fa-edit"></span> {% trans 'Preferences' %}</a></li>
{% endif %} {% endif %}
<li><a href="{% url 'ClientDownload' %}"><span class="fa fa-download"></span> {% trans 'UDS Plugin' %}</a></li>
{% if user.staff_member or user.is_admin %} {% if user.staff_member or user.is_admin %}
<li><a href="{% url "uds.web.views.download" idDownload='' %}"><span class="fa fa-download"></span> {% trans "Downloads" %}</a></li> <li><a href="{% url "uds.web.views.download" idDownload='' %}"><span class="fa fa-download"></span> {% trans "Downloads" %}</a></li>
{% ifbrowser ie<8 %} {% ifbrowser ie<8 %}

View File

@ -52,7 +52,7 @@ import logging
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
__updated__ = '2017-10-25' __updated__ = '2017-11-10'
def about(request): def about(request):
@ -120,29 +120,32 @@ def index(request):
'link': link 'link': link
} }
) )
if svr.deployed_service.image is not None:
imageId = svr.deployed_service.image.uuid servicePool = svr.deployed_service
if servicePool.image is not None:
imageId = servicePool.image.uuid
else: else:
imageId = 'x' # Invalid imageId = 'x' # Invalid
# Extract app group # Extract app group
group = svr.deployed_service.servicesPoolGroup if svr.deployed_service.servicesPoolGroup is not None else ServicesPoolGroup.default().as_dict group = servicePool.servicesPoolGroup if servicePool.servicesPoolGroup is not None else ServicesPoolGroup.default().as_dict
services.append({ services.append({
'id': 'A' + svr.uuid, 'id': 'A' + svr.uuid,
'name': svr.name, 'name': servicePool.name,
'visual_name': svr.visual_name, 'visual_name': servicePool.visual_name,
'description': svr.deployed_service.comments, 'description': servicePool.comments,
'group': group, 'group': group,
'transports': trans, 'transports': trans,
'imageId': imageId, 'imageId': imageId,
'show_transports': svr.deployed_service.show_transports, 'show_transports': servicePool.show_transports,
'allow_users_remove': svr.deployed_service.allow_users_remove, 'allow_users_remove': servicePool.allow_users_remove,
'maintenance': svr.deployed_service.isInMaintenance(), 'maintenance': servicePool.isInMaintenance(),
'not_accesible': not svr.deployed_service.isAccessAllowed(), 'not_accesible': not servicePool.isAccessAllowed(),
'in_use': svr.in_use, 'in_use': svr.in_use,
'to_be_replaced': False, # Manually assigned will not be autoremoved never 'to_be_replaced': False, # Manually assigned will not be autoremoved never
'comments': svr.comments, 'comments': servicePool.comments,
}) })
logger.debug(services) logger.debug(services)