1
0
mirror of https://github.com/dkmstr/openuds.git synced 2024-12-22 13:34:04 +03:00

Advancing admin (in fact already playing around with components, but made some advances.. :-) )

This commit is contained in:
Adolfo Gómez 2013-11-14 17:02:30 +00:00
parent d68822eaf7
commit 0a0772a7c6
14 changed files with 516 additions and 41 deletions

View File

@ -12,7 +12,10 @@ encoding//src/uds/REST/__init__.py=utf-8
encoding//src/uds/REST/handlers.py=utf-8
encoding//src/uds/REST/methods/authentication.py=utf-8
encoding//src/uds/REST/methods/authenticators.py=utf-8
encoding//src/uds/REST/methods/networks.py=utf-8
encoding//src/uds/REST/methods/osmanagers.py=utf-8
encoding//src/uds/REST/methods/providers.py=utf-8
encoding//src/uds/REST/methods/transports.py=utf-8
encoding//src/uds/REST/mixins.py=utf-8
encoding//src/uds/REST/processors.py=utf-8
encoding//src/uds/__init__.py=utf-8

View File

@ -55,14 +55,10 @@ class Authenticators(ModelHandlerMixin, Handler):
'users_count': auth.users.count(),
'type': type_.type(),
'comments': auth.comments,
'type_name': type_.name(),
}
class Types(ModelTypeHandlerMixin, Handler):
path = 'authenticators'
model = Authenticator
def enum_types(self):
return auths.factory().providers().values()

View File

@ -0,0 +1,72 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2014 Virtual Cable S.L.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
'''
@itemor: Adolfo Gómez, dkmaster at dkmon dot com
'''
from __future__ import unicode_literals
from django.utils.translation import ugettext_lazy as _
from uds.models import Network
from uds.REST import Handler, HandlerError
from uds.REST.mixins import ModelHandlerMixin, ModelTypeHandlerMixin, ModelTableHandlerMixin, ModelFakeType
import logging
logger = logging.getLogger(__name__)
# Enclosed methods under /item path
class Networks(ModelHandlerMixin, Handler):
model = Network
def item_as_dict(self, item):
return { 'id': item.id,
'name': item.name,
'net_string': item.net_string,
'networks_count': item.transports.count(),
'type': 'NetworkType',
}
class Types(ModelTypeHandlerMixin, Handler):
path = 'networks'
# Fake mathods, to yield self on enum types and get a "fake" type for Network
def enum_types(self):
yield ModelFakeType('Network', 'NetworkType', 'A description of a network', '')
class TableInfo(ModelTableHandlerMixin, Handler):
path = 'networks'
title = _('Current Networks')
fields = [
{ 'name': {'title': _('Name'), 'visible': True } },
{ 'net_string': {'title': _('Networks')}},
{ 'networks_count': {'title': _('Used by'), 'type': 'numeric', 'width': '8em'}}
]

View File

@ -0,0 +1,74 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2014 Virtual Cable S.L.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
'''
@osmor: Adolfo Gómez, dkmaster at dkmon dot com
'''
from __future__ import unicode_literals
from django.utils.translation import ugettext_lazy as _
from uds.models import OSManager
from uds.core.osmanagers import factory
from uds.REST import Handler, HandlerError
from uds.REST.mixins import ModelHandlerMixin, ModelTypeHandlerMixin, ModelTableHandlerMixin
import logging
logger = logging.getLogger(__name__)
# Enclosed methods under /osm path
class OsManagers(ModelHandlerMixin, Handler):
model = OSManager
def item_as_dict(self, osm):
type_ = osm.getType()
return { 'id': osm.id,
'name': osm.name,
'deployed_count': osm.deployedServices.count(),
'type': type_.type(),
'comments': osm.comments,
}
class Types(ModelTypeHandlerMixin, Handler):
path = 'osmanagers'
model = OsManagers
def enum_types(self):
return factory().providers().values()
class TableInfo(ModelTableHandlerMixin, Handler):
path = 'osmanagers'
title = _('Current OS Managers')
fields = [
{ 'name': {'title': _('Name'), 'visible': True } },
{ 'comments': {'title': _('Comments')}},
{ 'deployed_count': {'title': _('Used by'), 'type': 'numeric', 'width': '8em'}}
]

View File

@ -54,12 +54,10 @@ class Providers(ModelHandlerMixin, Handler):
'services_count': provider.services.count(),
'type': type_.type(),
'comments': provider.comments,
'type_name': type_.name(),
}
class Types(ModelTypeHandlerMixin, Handler):
path = 'providers'
model = Provider
def enum_types(self):
return services.factory().providers().values()
@ -68,7 +66,7 @@ class TableInfo(ModelTableHandlerMixin, Handler):
path = 'providers'
title = _('Current service providers')
fields = [
{ 'name': {'title': _('Name')} },
{ 'name': {'title': _('Name') } },
{ 'comments': {'title': _('Comments')}},
{ 'services_count': {'title': _('Services'), 'type': 'numeric', 'width': '5em'}}
]

View File

@ -0,0 +1,74 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2014 Virtual Cable S.L.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
'''
@itemor: Adolfo Gómez, dkmaster at dkmon dot com
'''
from __future__ import unicode_literals
from django.utils.translation import ugettext_lazy as _
from uds.models import Transport
from uds.core.transports import factory
from uds.REST import Handler, HandlerError
from uds.REST.mixins import ModelHandlerMixin, ModelTypeHandlerMixin, ModelTableHandlerMixin
import logging
logger = logging.getLogger(__name__)
# Enclosed methods under /item path
class Transports(ModelHandlerMixin, Handler):
model = Transport
def item_as_dict(self, item):
type_ = item.getType()
return { 'id': item.id,
'name': item.name,
'priority': item.priority,
'deployed_count': item.deployedServices.count(),
'type': type_.type(),
'comments': item.comments
}
class Types(ModelTypeHandlerMixin, Handler):
path = 'transports'
def enum_types(self):
return factory().providers().values()
class TableInfo(ModelTableHandlerMixin, Handler):
path = 'transports'
title = _('Current Transports')
fields = [
{ 'name': {'title': _('Name'), 'visible': True } },
{ 'comments': {'title': _('Comments')}},
{ 'deployed_count': {'title': _('Used by'), 'type': 'numeric', 'width': '8em'}}
]

View File

@ -54,7 +54,10 @@ class ModelHandlerMixin(object):
def getItems(self, *args, **kwargs):
for item in self.model.objects.filter(*args, **kwargs):
yield self.item_as_dict(item)
try:
yield self.item_as_dict(item)
except:
logger.exception('Exception getting item from {0}'.format(self.model))
def get(self):
logger.debug('methot GET for {0}'.format(self.__class__.__name__))
@ -72,7 +75,6 @@ class ModelTypeHandlerMixin(object):
'''
authenticated = True
needs_staff = True
model = None
def enum_types(self):
pass
@ -86,7 +88,10 @@ class ModelTypeHandlerMixin(object):
def getTypes(self, *args, **kwargs):
for type_ in self.enum_types():
yield self.type_as_dict(type_)
try:
yield self.type_as_dict(type_)
except:
logger.exception('Exception enumerating types')
def get(self):
return list(self.getTypes())
@ -121,3 +126,13 @@ class ModelTableHandlerMixin(object):
fields.append({k1: dct})
return { 'title': unicode(self.title), 'fields': fields };
# Fake type for models that do not needs typing
class ModelFakeType(object):
def __init__(self, name, type_, description, icon):
self._name, self._type, self._description, self._icon = name, type_, description, icon
def name(self): return self._name
def type(self): return self._type
def description(self): return self._description
def icon(self): return self._icon

View File

@ -100,4 +100,6 @@ BasicModelRest.prototype = {
api.providers = new BasicModelRest('providers');
//api.services = new BasicModelRest('services');
api.authenticators = new BasicModelRest('authenticators');
api.osmanagers = new BasicModelRest('osmanagers');
api.transports = new BasicModelRest('transports');
api.networks = new BasicModelRest('networks');

View File

@ -38,9 +38,9 @@
if( options.icon == undefined )
options.icon = 'table';
return '<div class="col-lg-' + options.size + '"><div class="panel panel-primary"><div class="panel-heading">'+
return '<div class="panel panel-primary"><div class="panel-heading">'+
'<h3 class="panel-title"><span class="fa fa-'+ options.icon + '"></span> ' + title + '</h3></div>'+
'<div class="panel-body"><table class="display" id="' + table_id + '"></table></div></div></div>';
'<div class="panel-body"><table class="display" id="' + table_id + '"></table></div></div>';
}
gui.breadcrumbs = function(path) {
@ -72,17 +72,6 @@
gui.doLog(this);
};
gui.osmanagers = function() {
gui.clearWorkspace();
gui.appendToWorkspace(gui.breadcrumbs('OS Managers'));
}
gui.connectivity = function() {
gui.clearWorkspace();
gui.appendToWorkspace(gui.breadcrumbs(gettext('Connectivity')));
}
gui.deployed_services = function() {
gui.clearWorkspace();
gui.appendToWorkspace(gui.breadcrumbs(gettext('Deployed services')));
@ -93,8 +82,8 @@
{ id: 'lnk-dashboard', exec: gui.dashboard },
{ id: 'lnk-service_providers', exec: gui.providers.link },
{ id: 'lnk-authenticators', exec: gui.authenticators.link },
{ id: 'lnk-osmanagers', exec: gui.osmanagers },
{ id: 'lnk-connectivity', exec: gui.connectivity },
{ id: 'lnk-osmanagers', exec: gui.osmanagers.link },
{ id: 'lnk-connectivity', exec: gui.connectivity.link },
{ id: 'lnk-deployed_services', exec: gui.deployed_services },
];
$.each(sidebarLinks, function(index, value){
@ -112,19 +101,24 @@
gui.debug = true;
}(window.gui = window.gui || {}, jQuery));
function GuiElement(restItem) {
function GuiElement(restItem, name) {
this.rest = restItem;
this.name = name;
this.types = {}
this.init();
}
// all gui elements has, at least, name && type
// Types must include, at least: type, icon
GuiElement.prototype = {
init: function() {
gui.doLog('Initializing ' + this.rest.path);
gui.doLog('Initializing ' + this.name);
var $this = this;
this.rest.types(function(data){
var styles = '<style media="screen">';
$.each(data, function(index, value){
var className = $this.rest.path + '-' + value.type;
var className = $this.name + '-' + value.type;
$this.types[value.type] = { css: className, name: value.name || '', description: value.description || '' };
gui.doLog('Creating style for ' + className )
var style = '.' + className +
' { display:inline-block; background: url(data:image/png;base64,' + value.icon + '); ' +
@ -135,15 +129,15 @@ GuiElement.prototype = {
$(styles).appendTo('head');
});
},
table: function(options) {
table: function(container_id) {
// Empty container_id first
gui.doLog('Composing table for ' + this.rest.path);
var tableId = this.rest.path + '-table';
gui.doLog('Composing table for ' + this.name);
var tableId = this.name + '-table';
var $this = this;
this.rest.tableInfo(function(data){
var title = data.title;
var columns = [];
$.each(data.fields,function(index, value) {
$.each(data.fields,function(index, value) {
for( var v in value ){
var options = value[v];
gui.doLog(options);
@ -155,19 +149,38 @@ GuiElement.prototype = {
column.sWidth = options.width;
if( options.visible != undefined )
column.bVisible = options.visible;
if( options.sortable != undefined )
column.bSortable = options.sortable;
// Fix name columm so we can add a class icon
if( v == 'name' ) {
column.sType ='html'
}
columns.push(column);
}
});
gui.doLog(columns);
$this.rest.get({
success: function(data) {
var table = gui.table(title, tableId, options);
gui.appendToWorkspace('<div class="row">' + table + '</div>');
$('#' + tableId).dataTable( {
$.each(data, function(index, value){
var type = $this.types[value.type];
data[index].name = '<span class="' + type.css + '"></span> ' + value.name
});
var table = gui.table(title, tableId);
if( container_id == undefined ) {
gui.appendToWorkspace('<div class="row"><div class="col-lg-12">' + table + '</div></div>');
} else {
$('#'+container_id).empty();
$('#'+container_id).append(table);
}
$('#' + tableId).dataTable({
"aaData": data,
"aoColumns": columns,
"oLanguage": gui.dataTablesLanguage,
} )
});
}
});
});
@ -179,7 +192,7 @@ GuiElement.prototype = {
// Compose gui API
// Service providers
gui.providers = new GuiElement(api.providers);
gui.providers = new GuiElement(api.providers, 'prov'); // Tha 'name' must be the same as uses on REST api
gui.providers.link = function(event) {
gui.clearWorkspace();
gui.appendToWorkspace(gui.breadcrumbs(gettext('Service Providers')));
@ -189,7 +202,7 @@ gui.providers.link = function(event) {
return false;
};
gui.authenticators = new GuiElement(api.authenticators);
gui.authenticators = new GuiElement(api.authenticators, 'auth');
gui.authenticators.link = function(event) {
gui.clearWorkspace();
gui.appendToWorkspace(gui.breadcrumbs(gettext('Authenticators')));
@ -197,4 +210,28 @@ gui.authenticators.link = function(event) {
gui.authenticators.table();
return false;
};
};
gui.osmanagers = new GuiElement(api.osmanagers, 'osm');
gui.osmanagers.link = function(event) {
gui.clearWorkspace();
gui.appendToWorkspace(gui.breadcrumbs('Os Managers'));
gui.osmanagers.table();
return false;
};
gui.connectivity = {
transports: new GuiElement(api.transports, 'trans'),
networks: new GuiElement(api.networks, 'nets'),
};
gui.connectivity.link = function(event) {
gui.clearWorkspace();
gui.appendToWorkspace(gui.breadcrumbs(gettext('Connectivity')));
gui.appendToWorkspace('<div class="row"><div class="col-lg-6" id="ttbl"></div><div class="col-lg-6" id="ntbl"></div></div>');
gui.connectivity.transports.table('ttbl');
gui.connectivity.networks.table('ntbl');
}

View File

@ -0,0 +1,204 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2012 Virtual Cable S.L.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
'''
Created on Jul 29, 2011
@author: Adolfo Gómez, dkmaster at dkmon dot com
'''
from django.utils.translation import ugettext_noop as _
from uds.core.managers.UserPrefsManager import CommonPrefs
from uds.core.ui.UserInterface import gui
from uds.core.transports.BaseTransport import Transport
from uds.core.util.Cache import Cache
from uds.core.util import connection
from web import generateHtmlForNX, getHtmlComponent
import logging, random, string, time
logger = logging.getLogger(__name__)
READY_CACHE_TIMEOUT = 30
class TSNXTransport(Transport):
'''
Provides access via RDP to service.
This transport can use an domain. If username processed by authenticator contains '@', it will split it and left-@-part will be username, and right password
'''
typeName = _('NX Transport (tunneled)')
typeType = 'TSNXTransport'
typeDescription = _('NX Transport for tunneled connection')
iconFile = 'nx.png'
needsJava = True # If this transport needs java for rendering
supportedOss = ['Windows', 'Macintosh', 'Linux']
tunnelServer = gui.TextField(label=_('Tunnel server'), order = 1, tooltip = _('IP or Hostname of tunnel server send to client device ("public" ip) and port. (use HOST:PORT format)'))
tunnelCheckServer = gui.TextField(label=_('Tunnel host check'), order = 2, tooltip = _('If not empty, this server will be used to check if service is running before assigning it to user. (use HOST:PORT format)'))
useEmptyCreds = gui.CheckBoxField(label = _('Empty creds'), order = 3, tooltip = _('If checked, the credentials used to connect will be emtpy'))
fixedName = gui.TextField(label=_('Username'), order = 4, tooltip = _('If not empty, this username will be always used as credential'))
fixedPassword = gui.PasswordField(label=_('Password'), order = 5, tooltip = _('If not empty, this password will be always used as credential'))
listenPort = gui.NumericField(label=_('Listen port'), length = 5, order = 6, tooltip = _('Listening port of NX (ssh) at client machine'), defvalue = '22')
connection = gui.ChoiceField(label=_('Connection'), order = 7, tooltip = _('Connection speed for this transport (quality)'), values = [
{'id' : 'modem', 'text' : 'modem'},
{'id' : 'isdn', 'text' : 'isdn'},
{'id' : 'adsl', 'text' : 'adsl'},
{'id' : 'wan', 'text' : 'wan'},
{'id' : 'lan', 'text' : 'lan'},
] )
session = gui.ChoiceField(label=_('Session'), order = 8, tooltip = _('Desktop session'), values = [
{'id' : 'gnome', 'text' : 'gnome'},
{'id' : 'kde', 'text' : 'kde'},
{'id' : 'cde', 'text' : 'cde'},
] )
cacheDisk = gui.ChoiceField(label=_('Disk Cache'), order = 9, tooltip = _('Cache size en Mb stored at disk'), values = [
{'id' : '0', 'text' : '0 Mb'},
{'id' : '32', 'text' : '32 Mb'},
{'id' : '64', 'text' : '64 Mb'},
{'id' : '128', 'text' : '128 Mb'},
{'id' : '256', 'text' : '256 Mb'},
{'id' : '512', 'text' : '512 Mb'},
] )
cacheMem = gui.ChoiceField(label=_('Memory Cache'), order = 10, tooltip = _('Cache size en Mb keept at memory'), values = [
{'id' : '4', 'text' : '4 Mb'},
{'id' : '8', 'text' : '8 Mb'},
{'id' : '16', 'text' : '16 Mb'},
{'id' : '32', 'text' : '32 Mb'},
{'id' : '64', 'text' : '64 Mb'},
{'id' : '128', 'text' : '128 Mb'},
] )
def __init__(self, environment, values = None):
super(TSNXTransport, self).__init__(environment, values)
if values != None:
if values['tunnelServer'].find(':') == -1:
raise Transport.ValidationException(_('Must use HOST:PORT in Tunnel Server Field'))
self._tunnelServer = values['tunnelServer']
self._tunnelCheckServer = values['tunnelCheckServer']
self._useEmptyCreds = gui.strToBool(values['useEmptyCreds'])
self._fixedName = values['fixedName']
self._fixedPassword = values['fixedPassword']
self._listenPort = values['listenPort']
self._connection = values['connection']
self._session = values['session']
self._cacheDisk = values['cacheDisk']
self._cacheMem = values['cacheMem']
else:
self._tunnelServer = ''
self._tunnelCheckServer = ''
self._useEmptyCreds = ''
self._fixedName = ''
self._fixedPassword = ''
self._listenPort = ''
self._connection = ''
self._session = ''
self._cacheDisk = ''
self._cacheMem = ''
def marshal(self):
'''
Serializes the transport data so we can store it in database
'''
return str.join( '\t', [ 'v1', gui.boolToStr(self._useEmptyCreds), self._fixedName, self._fixedPassword, self._listenPort,
self._connection, self._session, self._cacheDisk, self._cacheMem, self._tunnelServer, self._tunnelCheckServer ] )
def unmarshal(self, string):
data = string.split('\t')
if data[0] == 'v1':
self._useEmptyCreds = gui.strToBool(data[1])
self._fixedName, self._fixedPassword, self._listenPort, self._connection, self._session, self._cacheDisk, self._cacheMem, self._tunnelServer, self._tunnelCheckServer = data[2:]
def valuesDict(self):
return { 'useEmptyCreds' : gui.boolToStr(self._useEmptyCreds), 'fixedName' : self._fixedName,
'fixedPassword' : self._fixedPassword, 'listenPort': self._listenPort,
'connection' : self._connection, 'session' : self._session, 'cacheDisk' : self._cacheDisk,
'cacheMem' : self._cacheMem, 'tunnelServer' : self._tunnelServer,
'tunnelCheckServer' : self._tunnelCheckServer }
def isAvailableFor(self, ip):
'''
Checks if the transport is available for the requested destination ip
Override this in yours transports
'''
logger.debug('Checking availability for {0}'.format(ip))
ready = self.cache().get(ip)
if ready is None:
# Check again for readyness
if connection.testServer(ip, self._listenPort) == True:
self.cache().put(ip, 'Y', READY_CACHE_TIMEOUT)
return True
else:
self.cache().put(ip, 'N', READY_CACHE_TIMEOUT)
return ready == 'Y'
def renderForHtml(self, userService, idUserService, idTransport, ip, os, user, password):
prefs = user.prefs('nx')
username = user.getUsernameForAuth()
proc = username.split('@')
username = proc[0]
if self._fixedName is not '':
username = self._fixedName
if self._fixedPassword is not '':
password = self._fixedPassword
if self._useEmptyCreds is True:
username, password = '',''
width, height = CommonPrefs.getWidthHeight(prefs)
cache = Cache('pam')
tunuser = ''.join(random.choice(string.letters + string.digits) for i in xrange(12)) + ("%f" % time.time()).split('.')[1]
tunpass = ''.join(random.choice(string.letters + string.digits) for i in xrange(12))
cache.put(tunuser, tunpass, 60*10) # Credential valid for ten minutes, and for 1 use only
sshHost, sshPort = self._tunnelServer.split(':')
logger.debug('Username generated: {0}, password: {1}'.format(tunuser, tunpass))
tun = "{0} {1} {2} {3} {4} {5} {6}".format(tunuser, tunpass, sshHost, sshPort, ip, self._listenPort, '9')
# Extra data
extra = { 'width': width, 'height' : height,
'connection' : self._connection,
'session' : self._session, 'cacheDisk': self._cacheDisk,
'cacheMem' : self._cacheMem, 'tun' : tun }
# Fix username/password acording to os manager
username, password = userService.processUserPassword(username, password)
return generateHtmlForNX(self, idUserService, idTransport, os, username, password, extra)
def getHtmlComponent(self, theId, os, componentId):
# We use helper to keep this clean
return getHtmlComponent(self.__module__, componentId)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 857 B

View File

@ -55,7 +55,7 @@ class TSNXTransport(Transport):
typeName = _('NX Transport (tunneled)')
typeType = 'TSNXTransport'
typeDescription = _('NX Transport for tunneled connection')
iconFile = 'tsnx.png'
iconFile = 'nx.png'
needsJava = True # If this transport needs java for rendering
supportedOss = ['Windows', 'Macintosh', 'Linux']

Binary file not shown.

After

Width:  |  Height:  |  Size: 857 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB