Compare commits

...

21 Commits

Author SHA1 Message Date
Adolfo Gómez García
668578826e added .gitignore to version 2014-09-03 18:29:09 +02:00
Adolfo Gómez
646f4fadfb Updated NX download urls to new locations
Added configuration parameters to allow change these urls
2013-10-18 08:23:07 +00:00
Adolfo Gómez
158ac77727 * Updated URLS for NX (to 3.5 version ones)
* Added urls to a new configuration pannel (NX)
2013-10-18 08:07:15 +00:00
Adolfo Gómez
47ea0a3bcb sorted to show virtual pcvs 2013-10-16 11:41:12 +00:00
Adolfo Gómez
3646c9dec9 fixed where to get fixed credentials 2013-10-16 11:36:17 +00:00
Adolfo Gómez
d5e71be73c fixed where to get fixed credentials 2013-10-16 11:26:58 +00:00
Adolfo Gómez
1ea5987975 updated to avoid JAva warning about permissions 2013-10-16 10:56:58 +00:00
Adolfo Gómez
32ffe5e2d7 Fixed DelayedTask Class to include new "register" member from trunk 2013-10-15 07:57:18 +00:00
Adolfo Gómez
add4c58128 updated guacamole package paths 2013-10-03 13:55:42 +00:00
Adolfo Gómez
6488f0e80d Updated java version 2013-10-03 13:52:20 +00:00
Adolfo Gómez
8a3ea8f4c9 Updated bad config 2013-10-02 06:07:25 +00:00
Adolfo Gómez
bf47f40939 Updated to allow audio redirection, and newer build methods. 2013-10-02 03:07:36 +00:00
Adolfo Gómez
7e8fa876fa Added audio support selection 2013-10-02 02:58:17 +00:00
Adolfo Gómez
dbe7e5187b Fixed a couple of typo bugs on RDP Transports 2013-10-01 20:47:16 +00:00
Adolfo Gómez
808dfa5aa0 Merge of bug fixes done on trunk 2013-09-26 04:57:09 +00:00
Adolfo Gómez
7a3eccc5ba 2013-09-26 04:27:42 +00:00
Adolfo Gómez
a3348c9299 Tagging for merging bug fixes done on trunk 2013-09-26 04:26:16 +00:00
Adolfo Gómez
f53b8fee61 Failed to copy a file from trunk :-) 2013-06-27 09:16:43 +00:00
Adolfo Gómez
5047225ea0 Fixed a possible bug on 1.2 with IP authenticator, and improved it 2013-06-25 15:42:53 +00:00
Adolfo Gómez
44da266276 Added new 1.2 tag 2013-06-25 08:25:44 +00:00
Adolfo Gómez
a7b5b85c05 Tag for 1.2 version 2013-05-10 10:15:42 +00:00
32 changed files with 517 additions and 136 deletions

165
.gitignore vendored Normal file
View File

@ -0,0 +1,165 @@
*.pyc
# Debian buildings
*.debhelper*
*-stamp
*.substvars
nxtransport/bin/
nxtuntransport/bin/
rdptransport/java/bin/
server/src/log/
ssh-tunnel/tunnelLaucher/bin/
# /client/administration/
/client/administration/*.suo
# /client/administration/UdsAdmin/
/client/administration/UdsAdmin/*.user
# /client/administration/UdsAdmin/bin/
/client/administration/UdsAdmin/bin/Debug
/client/administration/UdsAdmin/bin/Release
# /client/administration/UdsAdmin/obj/x86/
/client/administration/UdsAdmin/obj/x86/Debug
/client/administration/UdsAdmin/obj/x86/Release
# /client/administration/installer/UDSAdminInstaller/
/client/administration/installer/UDSAdminInstaller/MSChart.exe
/client/administration/installer/UDSAdminInstaller/UDSAdminSetup.exe
# /guacamole-tunnel/
/guacamole-tunnel/target
# /linuxActor/
/linuxActor/udsactor_*
# /linuxActor/src/debian/
/linuxActor/src/debian/udsactor
# /linuxActorNX/
/linuxActorNX/udsactor-nx_*
# /linuxActorNX/src/debian/
/linuxActorNX/src/debian/udsactor-nx
# /linuxActorXRDP/
/linuxActorXRDP/udsactor-xrdp_*
# /linuxActorXRDP/src/debian/
/linuxActorXRDP/src/debian/udsactor-xrdp
# /nxtransport/jar/
/nxtransport/jar/*.sh
/nxtransport/jar/*.jar
# /nxtuntransport/jar/
/nxtuntransport/jar/*.sh
/nxtuntransport/jar/*.jar
# /rdptransport/java/jar/
/rdptransport/java/jar/*.sh
/rdptransport/java/jar/*.jar
# /server/
/server/*_enterprise
/server/openuds.sublime-project
/server/openuds.sublime-workspace
# /server/src/
/server/src/taskmanager.pid
/server/src/testing
/server/src/*_enterprise*
# /server/src/log/
/server/src/log/uds.log.*
/server/src/log/sql.log.*
/server/src/log/*.log.*
# /server/src/server/
/server/src/server/settings.py
/server/src/server/*_enterprise.py
/server/src/server/enterprise*
# /server/src/static/
/server/src/static/cache
# /server/src/uds/
/server/src/uds/*_enterprise.py
/server/src/uds/fixtures
/server/src/uds/tests
# /server/src/uds/auths/
/server/src/uds/auths/*-enterprise
/server/src/uds/auths/*_enterprise
# /server/src/uds/core/util/
/server/src/uds/core/util/*enterprise.py
# /server/src/uds/dispatchers/
/server/src/uds/dispatchers/*_enterprise
# /server/src/uds/locale/
/server/src/uds/locale/*.sh
# /server/src/uds/management/commands/
/server/src/uds/management/commands/*_enterprise.py
# /server/src/uds/models/
/server/src/uds/models/enterprise*
# /server/src/uds/plugins/
/server/src/uds/plugins/enterprise*
# /server/src/uds/services/
/server/src/uds/services/*-enterprise
/server/src/uds/services/*_enterprise
# /server/src/uds/static/adm/css/
/server/src/uds/static/adm/css/admin.min.css
# /server/src/uds/static/adm/js/
/server/src/uds/static/adm/js/admin.min.js
# /server/src/uds/templates/uds/admin/
/server/src/uds/templates/uds/admin/sample.html
# /server/src/uds/transports/
/server/src/uds/transports/*-enterprise
# /udsService/
/udsService/*.suo
# /udsService/installer/
/udsService/installer/UDSActorSetup.exe
# /udsService/rpc/bin/
/udsService/rpc/bin/Debug
/udsService/rpc/bin/Release
/udsService/rpc/bin/x86
# /udsService/rpc/obj/
/udsService/rpc/obj/Debug
/udsService/rpc/obj/Release
/udsService/rpc/obj/x86
# /udsService/udsService/bin/
/udsService/udsService/bin/Debug
/udsService/udsService/bin/Release
/udsService/udsService/bin/x64
# /udsService/udsService/obj/
/udsService/udsService/obj/x64
/udsService/udsService/obj/x86
# /udsService/udsgui/bin/
/udsService/udsgui/bin/Debug
/udsService/udsgui/bin/Release
/udsService/udsgui/bin/x86
# /udsService/udsgui/obj/
/udsService/udsgui/obj/Debug
/udsService/udsgui/obj/Release
/udsService/udsgui/obj/x86

11
.project Normal file
View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>uds</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
</buildSpec>
<natures>
</natures>
</projectDescription>

View File

@ -1,9 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src/main/java" including="**/*.java"/>
<classpathentry kind="output" path="target/classes"/>
<classpathentry kind="var" path="M2_REPO/javax/servlet/servlet-api/2.5/servlet-api-2.5.jar"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="var" path="M2_REPO/net/sourceforge/guacamole/guacamole-common/0.7.0/guacamole-common-0.7.0.jar"/>
<classpathentry kind="var" path="M2_REPO/org/slf4j/slf4j-api/1.6.1/slf4j-api-1.6.1.jar"/>
</classpath>
<classpathentry kind="var" path="M2_REPO/javax/servlet/servlet-api/2.5/servlet-api-2.5.jar"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="var" path="M2_REPO/net/sourceforge/guacamole/guacamole-common/0.7.0/guacamole-common-0.7.0.jar"/>
<classpathentry kind="var" path="M2_REPO/org/slf4j/slf4j-api/1.6.1/slf4j-api-1.6.1.jar"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>

View File

@ -4,10 +4,10 @@
http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>net.sourceforge.guacamole</groupId>
<groupId>org.openuds.server</groupId>
<artifactId>transport</artifactId>
<packaging>war</packaging>
<version>1.2.0</version>
<version>1.2.1</version>
<name>Guacamole Transport</name>
<url>http://openuds.org/</url>
@ -36,7 +36,7 @@
<configuration>
<overlays>
<overlay>
<groupId>net.sourceforge.guacamole</groupId>
<groupId>org.glyptodon.guacamole</groupId>
<artifactId>guacamole-common-js</artifactId>
<type>zip</type>
</overlay>
@ -60,16 +60,17 @@
<!-- Main Guacamole library -->
<dependency>
<groupId>net.sourceforge.guacamole</groupId>
<groupId>org.glyptodon.guacamole</groupId>
<artifactId>guacamole-common</artifactId>
<version>0.8.0</version>
<scope>compile</scope>
</dependency>
<!-- Guacamole JavaScript library -->
<dependency>
<groupId>net.sourceforge.guacamole</groupId>
<groupId>org.glyptodon.guacamole</groupId>
<artifactId>guacamole-common-js</artifactId>
<version>0.7.2</version>
<version>0.7.4</version>
<type>zip</type>
<scope>runtime</scope>
</dependency>
@ -77,13 +78,4 @@
</dependencies>
<repositories>
<!-- Main Guacamole repository -->
<repository>
<id>guac-dev</id>
<url>http://guac-dev.org/repo</url>
</repository>
</repositories>
</project>

View File

@ -3,21 +3,23 @@ package org.openuds.guacamole;
import java.io.BufferedReader;
import java.io.FileReader;
import java.net.URL;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Properties;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import net.sourceforge.guacamole.GuacamoleException;
import net.sourceforge.guacamole.net.GuacamoleSocket;
import net.sourceforge.guacamole.net.GuacamoleTunnel;
import net.sourceforge.guacamole.net.InetGuacamoleSocket;
import net.sourceforge.guacamole.protocol.ConfiguredGuacamoleSocket;
import net.sourceforge.guacamole.protocol.GuacamoleClientInformation;
import net.sourceforge.guacamole.protocol.GuacamoleConfiguration;
import net.sourceforge.guacamole.servlet.GuacamoleHTTPTunnelServlet;
import net.sourceforge.guacamole.servlet.GuacamoleSession;
import org.glyptodon.guacamole.GuacamoleException;
import org.glyptodon.guacamole.net.GuacamoleSocket;
import org.glyptodon.guacamole.net.GuacamoleTunnel;
import org.glyptodon.guacamole.net.InetGuacamoleSocket;
import org.glyptodon.guacamole.protocol.ConfiguredGuacamoleSocket;
import org.glyptodon.guacamole.protocol.GuacamoleClientInformation;
import org.glyptodon.guacamole.protocol.GuacamoleConfiguration;
import org.glyptodon.guacamole.servlet.GuacamoleHTTPTunnelServlet;
import org.glyptodon.guacamole.servlet.GuacamoleSession;
public class TunnelServlet
extends GuacamoleHTTPTunnelServlet {
@ -69,7 +71,6 @@ public class TunnelServlet
if( data == null || width == null || height == null)
throw new GuacamoleException("Can't read required parameters");
Hashtable<String,String> params = Util.readParameters( getConfigValue(UDS) + UDS_PATH + data);
if( params == null ) {
@ -82,6 +83,16 @@ public class TunnelServlet
GuacamoleClientInformation info = new GuacamoleClientInformation();
info.setOptimalScreenWidth(Integer.parseInt(width));
info.setOptimalScreenHeight(Integer.parseInt(height));
// Add audio mimetypes
String[] audio_mimetypes = request.getParameterValues("audio");
if (audio_mimetypes != null)
info.getAudioMimetypes().addAll(Arrays.asList(audio_mimetypes));
// Add video mimetypes
String[] video_mimetypes = request.getParameterValues("video");
if (video_mimetypes != null)
info.getVideoMimetypes().addAll(Arrays.asList(video_mimetypes));
// Create our configuration
GuacamoleConfiguration config = new GuacamoleConfiguration();

View File

@ -44,6 +44,109 @@
<script type="text/javascript" src="guacamole-common-js/audio.js"></script>
<script type="text/javascript" src="guacamole-common-js/guacamole.js"></script>
<script type="text/javascript" src="guacamole-common-js/oskeyboard.js"></script>
<script type="text/javascript"> /* <![CDATA[ */
/**
Get Audio supported items
*/
GuacAudio = new (function() {
var codecs = [
'audio/ogg; codecs="vorbis"',
'audio/mp4; codecs="mp4a.40.5"',
'audio/mpeg; codecs="mp3"',
'audio/webm; codecs="vorbis"',
'audio/wav; codecs=1'
];
var probably_supported = [];
var maybe_supported = [];
/**
* Array of all supported audio mimetypes, ordered by liklihood of
* working.
*/
this.supported = [];
// Build array of supported audio formats
codecs.forEach(function(mimetype) {
var audio = new Audio();
var support_level = audio.canPlayType(mimetype);
// Trim semicolon and trailer
var semicolon = mimetype.indexOf(";");
if (semicolon != -1)
mimetype = mimetype.substring(0, semicolon);
// Partition by probably/maybe
if (support_level == "probably")
probably_supported.push(mimetype);
else if (support_level == "maybe")
maybe_supported.push(mimetype);
});
// Add probably supported types first
Array.prototype.push.apply(
this.supported, probably_supported);
// Prioritize "maybe" supported types second
Array.prototype.push.apply(
this.supported, maybe_supported);
})();
GuacVideo = new (function() {
var codecs = [
'video/ogg; codecs="theora, vorbis"',
'video/mp4; codecs="avc1.4D401E, mp4a.40.5"',
'video/webm; codecs="vp8.0, vorbis"'
];
var probably_supported = [];
var maybe_supported = [];
/**
* Array of all supported video mimetypes, ordered by liklihood of
* working.
*/
this.supported = [];
// Build array of supported audio formats
codecs.forEach(function(mimetype) {
var video = document.createElement("video");
var support_level = video.canPlayType(mimetype);
// Trim semicolon and trailer
var semicolon = mimetype.indexOf(";");
if (semicolon != -1)
mimetype = mimetype.substring(0, semicolon);
// Partition by probably/maybe
if (support_level == "probably")
probably_supported.push(mimetype);
else if (support_level == "maybe")
maybe_supported.push(mimetype);
});
// Add probably supported types first
Array.prototype.push.apply(
this.supported, probably_supported);
// Prioritize "maybe" supported types second
Array.prototype.push.apply(
this.supported, maybe_supported);
})();
/* ]]> */
</script>
</head>
@ -80,10 +183,21 @@
// Get display div from document
var display = document.getElementById("display");
var tunnel;
// If WebSocket available, try to use it.
if (window.WebSocket)
tunnel = new Guacamole.ChainedTunnel(
new Guacamole.WebSocketTunnel("websocket-tunnel"),
new Guacamole.HTTPTunnel("tunnel")
);
// If no WebSocket, then use HTTP.
else
tunnel = new Guacamole.HTTPTunnel("tunnel")
// Instantiate client, using an HTTP tunnel for communications.
var guac = new Guacamole.Client(
new Guacamole.HTTPTunnel("tunnel")
);
var guac = new Guacamole.Client(tunnel);
// Add client to display div
@ -115,6 +229,15 @@
// the sake of authentication.
var connect_string = "data=" + data + "&width=" + optimal_width + "&height=" + optimal_height;
// Add audio mimetypes to connect_string
GuacAudio.supported.forEach(function(mimetype) {
connect_string += "&audio=" + encodeURIComponent(mimetype);
});
// Add video mimetypes to connect_string
GuacVideo.supported.forEach(function(mimetype) {
connect_string += "&video=" + encodeURIComponent(mimetype);
});
display.appendChild(inner);
guac.connect(connect_string);

View File

@ -38,6 +38,8 @@ from django.utils.translation import ugettext_noop as _
from uds.core.auths import Authenticator
from uds.core.auths.GroupsManager import GroupsManager
from uds.core.util import net
from uds.core.util.request import getRequest
import logging, random, string
logger = logging.getLogger(__name__)
@ -73,8 +75,7 @@ class IPAuth(Authenticator):
def authenticate(self, username, credentials, groupsManager):
# If credentials is a dict, that can't be sent directly from web interface, we allow entering
# We use this "trick" so authenticators
if self.cache().get(username) == credentials:
self.cache().remove(username)
if username == getRequest().ip:
self.getGroups(username, groupsManager)
return True
return False
@ -97,8 +98,7 @@ class IPAuth(Authenticator):
gm = GroupsManager(self.dbAuthenticator())
self.getGroups(request.ip, gm)
if gm.hasValidGroups() and self.dbAuthenticator().isValidUser(request.ip, True):
passw = ''.join(random.choice(string.letters + string.digits) for __ in xrange(12))
self.cache().put(request.ip, passw)
passw = ''
return '<script type="text/javascript">$("#id_user").val("' + request.ip + '");$("#id_password").val("' + passw + '");$("#loginform").submit();</script>'
else:
return '<div>This ip is not allowed to autologin (' + request.ip +')</div><script type="text/javascript">$("#backToLogin").click()</script>'

View File

@ -139,32 +139,33 @@ class RegexLdap(auths.Authenticator):
def __processField(self, field, attributes):
res = []
for line in field.splitlines():
equalPos = line.find('=')
if equalPos != -1:
attr, pattern = (line[:equalPos], line[equalPos+1:])
attr = attr.lower()
# if pattern do not have groups, define one with full re
if pattern.find('(') == -1:
pattern = '(' + pattern + ')'
val = attributes.get(attr, [])
if type(val) is not list: # May we have a single value
val = [val]
logger.debug('Pattern: {0}'.format(pattern))
for v in val:
try:
srch = re.search(pattern, v, re.IGNORECASE)
logger.debug("Found against {0}: {1} ".format(v, srch))
if srch is None:
continue
res.append(''.join(srch.groups()))
except Exception as e:
logger.warn('Invalid regular expression')
logger.debug(e)
break
else:
res += attributes.get(line, [])
equalPos = line.find('=')
if equalPos == -1:
line = line + '=(.*)'
equalPos = line.find('=')
attr, pattern = (line[:equalPos], line[equalPos+1:])
attr = attr.lower()
# if pattern do not have groups, define one with full re
if pattern.find('(') == -1:
pattern = '(' + pattern + ')'
val = attributes.get(attr, [])
if type(val) is not list: # May we have a single value
val = [val]
logger.debug('Pattern: {0}'.format(pattern))
for vv in val:
try:
v = vv.decode('utf-8')
srch = re.search(pattern, v, re.IGNORECASE)
logger.debug("Found against {0}: {1} ".format(v, srch))
if srch is None:
continue
res.append(''.join(srch.groups()))
except Exception as e:
logger.warn('Invalid regular expression')
logger.debug(e)
break
return res
def valuesDict(self):

View File

@ -55,3 +55,14 @@ class DelayedTask(Environmentable):
You must provide your own "run" method to do whatever you need
'''
logging.debug("Base run of job called for class")
def register(self, suggestedTime, tag='', check=True):
'''
Utility method that allows to register a Delayedtask
'''
from DelayedTaskRunner import DelayedTaskRunner
if check is True and DelayedTaskRunner.runner().checkExists(tag):
return
DelayedTaskRunner.runner().insert(self, suggestedTime, tag)

View File

@ -1,5 +1,4 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2012 Virtual Cable S.L.
# All rights reserved.
@ -30,11 +29,13 @@
'''
@author: Adolfo Gómez, dkmaster at dkmon dot com
'''
from __future__ import unicode_literals
from django.utils.translation import ugettext as _
from django.db import transaction
from uds.core.jobs.DelayedTask import DelayedTask
from uds.core.jobs.DelayedTaskRunner import DelayedTaskRunner
from uds.core.util.Config import GlobalConfig
from uds.core.services.Exceptions import PublishException
from uds.models import DeployedServicePublication, getSqlDatetime, State
import logging
@ -43,6 +44,26 @@ logger = logging.getLogger(__name__)
PUBTAG = 'pm-'
class PublicationOldMachinesCleaner(DelayedTask):
def __init__(self, publicationId):
super(PublicationOldMachinesCleaner,self).__init__()
self._id = publicationId
def run(self):
try:
dsp = DeployedServicePublication.objects.get(pk=self._id)
if (dsp.state!=State.REMOVABLE):
logger.info('Already removed')
now = getSqlDatetime()
activePub = dsp.deployed_service.activePublication()
dsp.deployed_service.userServices.filter(in_use=True).update(in_use=False, state_date=now)
dsp.deployed_service.markOldUserServicesAsRemovables(activePub)
except:
logger.info("Machine removal for {0} not executed because publication is already removed")
# Removed provider, no problem at all, no update is done
pass
class PublicationLauncher(DelayedTask):
def __init__(self, publish):
super(PublicationLauncher,self).__init__()
@ -81,31 +102,40 @@ class PublicationFinishChecker(DelayedTask):
Checks the value returned from invocation to publish or checkPublishingState, updating the dsp database object
Return True if it has to continue checking, False if finished
'''
prevState = dsp.state
checkLater = False
if State.isFinished(state):
# Now we mark, if it exists, the previous usable publication as "Removable"
if State.isPreparing(prevState):
dsp.deployed_service.publications.filter(state=State.USABLE).update(state=State.REMOVABLE)
dsp.setState(State.USABLE)
dsp.deployed_service.markOldUserServicesAsRemovables(dsp)
elif State.isRemoving(prevState):
dsp.setState(State.REMOVED)
else: # State is canceling
dsp.setState(State.CANCELED)
# Mark all previous publications deployed services as removables
# and make this usable
pi.finish()
dsp.updateData(pi)
elif State.isErrored(state):
dsp.updateData(pi)
dsp.state = State.ERROR
else:
checkLater = True # The task is running
dsp.updateData(pi)
dsp.save()
if checkLater:
try:
prevState = dsp.state
checkLater = False
if State.isFinished(state):
# Now we mark, if it exists, the previous usable publication as "Removable"
if State.isPreparing(prevState):
for old in dsp.deployed_service.publications.filter(state=State.USABLE):
old.state=State.REMOVABLE
old.save()
pc = PublicationOldMachinesCleaner(old.id)
pc.register(GlobalConfig.SESSION_EXPIRE_TIME.getInt(True)*3600, 'pclean-'+str(old.id), True)
dsp.setState(State.USABLE)
dsp.deployed_service.markOldUserServicesAsRemovables(dsp)
elif State.isRemoving(prevState):
dsp.setState(State.REMOVED)
else: # State is canceling
dsp.setState(State.CANCELED)
# Mark all previous publications deployed services as removables
# and make this usable
pi.finish()
dsp.updateData(pi)
elif State.isErrored(state):
dsp.updateData(pi)
dsp.state = State.ERROR
else:
checkLater = True # The task is running
dsp.updateData(pi)
dsp.save()
if checkLater:
PublicationFinishChecker.checkLater(dsp, pi)
except:
logger.exception('At checkAndUpdate for publication')
PublicationFinishChecker.checkLater(dsp, pi)
@staticmethod
@ -132,7 +162,6 @@ class PublicationFinishChecker(DelayedTask):
except Exception, e:
logger.debug('Deployed service not found (erased from database) {0} : {1}'.format(e.__class__, e))
class PublicationManager(object):
_manager = None

View File

@ -34,10 +34,10 @@ from __future__ import unicode_literals
from uds.core.managers.PublicationManager import PublicationManager
from uds.core.util.Config import GlobalConfig
from uds.models import DeployedServicePublication, DeployedService, getSqlDatetime
from uds.models import DeployedServicePublication, getSqlDatetime
from uds.core.services.Exceptions import PublishException
from uds.core.util.State import State
from uds.core.jobs.Job import Job
from uds.core.jobs import Job
from datetime import timedelta
import logging
@ -47,14 +47,14 @@ logger = logging.getLogger(__name__)
class PublicationInfoItemsCleaner(Job):
frecuency = GlobalConfig.CLEANUP_CHECK.getInt() # Request run cache "info" cleaner every configured seconds. If config value is changed, it will be used at next reload
friendly_name = 'Publications Info Cleaner'
now = getSqlDatetime()
def __init__(self, environment):
super(PublicationInfoItemsCleaner,self).__init__(environment)
def run(self):
removeFrom = getSqlDatetime() - timedelta(seconds = GlobalConfig.KEEP_INFO_TIME.getInt(True))
DeployedServicePublication.objects.filter(state__in=State.INFO_STATES, state_date__lt=removeFrom).delete()
class PublicationCleaner(Job):
frecuency = GlobalConfig.REMOVAL_CHECK.getInt() # Request run publication "removal" every configued seconds. If config value is changed, it will be used at next reload
friendly_name = 'Publication Cleaner'
@ -70,11 +70,3 @@ class PublicationCleaner(Job):
except PublishException: # Can say that it cant be removed right now
logger.debug('Delaying removal')
pass
# Now check too long "in use" services for all publications
now = getSqlDatetime()
removeFrom = now - timedelta(hours = GlobalConfig.SESSION_EXPIRE_TIME.getInt(True))
for dsp in removables.filter(state_date__lt=removeFrom):
activePub = dsp.deployed_service.activePublication()
dsp.deployed_service.userServices.filter(in_use=True).update(in_use=False, state_date=now)
dsp.deployed_service.markOldUserServicesAsRemovables(activePub)

View File

@ -1976,7 +1976,7 @@ class DelayedTask(models.Model):
#objects = LockingManager()
def __unicode__(self):
return u"Run Queue task {0} owned by {3},inserted at {1} and with {2} seconds delay".format(self.type, self.insert_date, self.execution_delay, self.owner_server)
return u"Run Queue task {0} owned by {3},inserted at {1} and with {2} seconds delay {3}".format(self.type, self.insert_date, self.execution_delay, self.execution_time)
class Network(models.Model):

View File

@ -265,7 +265,7 @@ class OVirtLinkedDeployment(UserDeployment):
if self._vmid != '': # Powers off
try:
state = self.service().getMachineState(self._vmid)
if state == 'up' and state == 'suspended':
if state in ('up', 'suspended'):
self.service().stopMachine(self._vmid)
except:
logger.debug('Can\t set machine state to stopped')

View File

@ -32,8 +32,9 @@ Created on Jun 22, 2012
.. moduleauthor:: Adolfo Gómez, dkmaster at dkmon dot com
'''
from __future__ import unicode_literals
from django.utils.translation import ugettext_noop as _, ugettext
from django.utils.translation import ugettext_noop as _
from uds.core.util.State import State
from uds.core.services import ServiceProvider
from OVirtLinkedService import OVirtLinkedService

View File

@ -90,6 +90,7 @@ class OVirtPublication(Publication):
try:
self._templateId = self.service().makeTemplate(self._name, comments)
except Exception as e:
self._state = 'error'
self._reason = str(e)
return State.ERROR
@ -151,6 +152,7 @@ class OVirtPublication(Publication):
try:
self.service().removeTemplate(self._templateId)
except Exception as e:
self._state = 'error'
self._reason = str(e)
return State.ERROR

View File

@ -51,8 +51,8 @@ class Client(object):
'''
global cached_api, cached_api_key
aKey = self.__getKey('o-host')
if cached_api_key == aKey:
return cached_api
#if cached_api_key == aKey:
# return cached_api
if cached_api is not None:
try:
@ -374,8 +374,8 @@ class Client(object):
display = params.Display(type_=displayType)
template = params.Template(name=name, vm=params.VM(id=vm.get_id(), disks=disks),
cluster=params.Cluster(id=cluster.get_id()), description=comments,
display=display)
cluster=params.Cluster(id=cluster.get_id()), description=comments)
#display=display)
return api.templates.add(template).get_id()
@ -442,7 +442,7 @@ class Client(object):
memoryPolicy = params.MemoryPolicy(guaranteed=guaranteedMB*1024*1024)
par = params.VM(name=name, cluster=cluster, template=template, description=comments,
display=display, type_='desktop', memory=memoryMB*1024*1024, memory_policy=memoryPolicy)
type_='desktop', memory=memoryMB*1024*1024, memory_policy=memoryPolicy) # display=display,
return api.vms.add(par).get_id()

View File

@ -62,6 +62,7 @@ class HTML5RDPTransport(Transport):
fixedName = gui.TextField(label=_('Username'), order = 3, tooltip = _('If not empty, this username will be always used as credential'))
fixedPassword = gui.PasswordField(label=_('Password'), order = 4, tooltip = _('If not empty, this password will be always used as credential'))
fixedDomain = gui.TextField(label=_('Domain'), order = 5, tooltip = _('If not empty, this domain will be always used as credential (used as DOMAIN\\user)'))
enableAudio = gui.CheckBoxField(label = _('Enable Audio'), order = 6, tooltip = _('If checked, the audio will be redirected to client (if client browser supports it)'))
def initialize(self, values):
if values is None:
@ -91,15 +92,16 @@ class HTML5RDPTransport(Transport):
import uuid
username = user.getUsernameForAuth()
if self.fixedName.value is not '':
username = self.fixedName.value
domain = ''
if username.find('@') != -1:
domain = username[username.find('@')+1:]
username, domain = username.split('@')
elif username.find('\\') != -1:
domain = username[:username.find('\\')]
domain, username = username.split('\\')
if self.fixedName.value is not '':
username = self.fixedName.value
if self.fixedPassword.value is not '':
password = self.fixedPassword.value
if self.fixedDomain.value is not '':
@ -114,10 +116,17 @@ class HTML5RDPTransport(Transport):
if domain.find('.') == -1:
username = domain + '\\' + username
else:
username = username + '@' + username
username = username + '@' + domain
# Build params dict
params = { 'protocol':'rdp', 'hostname':ip, 'username': username, 'password': password }
params = { 'protocol':'rdp',
'hostname':ip, 'username': username, 'password': password,
'ignore-cert': 'true',
}
if self.enableAudio.isTrue() is False:
params['disable-audio'] = 'true'
logger.debug('RDP Params: {0}'.format(params))

View File

@ -33,10 +33,15 @@
from uds.core.managers.UserPrefsManager import UserPrefsManager, CommonPrefs
from uds.core.managers.DownloadsManager import DownloadsManager
from uds.core.util.Config import Config
from NXTransport import NXTransport
from django.utils.translation import ugettext_noop as _
import os.path, sys
Config.section('NX').value('downloadUrl', 'http://www.nomachine.com/download-3').get()
Config.section('NX').value('downloadUrlMACOS', 'http://opennx.net/download.html').get()
UserPrefsManager.manager().registerPrefs('nx', _('NX Protocol'),
[
CommonPrefs.screenSizePref

View File

@ -34,6 +34,7 @@
from django.utils.translation import ugettext as _
from django.core.urlresolvers import reverse
from uds.core.util import OsDetector
from uds.core.util.Config import Config
import logging, os, sys
logger = logging.getLogger(__name__)
@ -75,24 +76,24 @@ def generateHtmlForNX(transport, idUserService, idTransport, ip, os, user, passw
]))
if isMac is True:
msg = '<p>' + _('In order to use this transport, you need to install first OpenNX Client for mac') + '</p>'
msg += '<p>' + _('You can oibtain it from ') + '<a href="http://opennx.net/download.html">' + _('OpenNx Website') + '</a></p>'
msg += '<p>' + _('You can oibtain it from ') + '<a href="{0}">'.format(Config.section('NX').value('downloadUrlMACOS').get()) + _('OpenNx Website') + '</a></p>'
else:
msg = '<p>' + _('In order to use this transport, you need to install first Nomachine Nx Client version 3.5.x') + '</p>'
msg +='<p>' + _('you can obtain it for your platform from') + '<a href="http://www.nomachine.com/download.php">' + _('nochamine web site') + '</a></p>'
res = '<div idTransport="applet"><applet code="NxTransportApplet.class" codebase="%s" archive="%s" width="140" height="22"><param name="data" value="%s"/></applet></div>' % (codebase, '1', data )
msg +='<p>' + _('you can obtain it for your platform from') + '<a href="{0}">'.format(Config.section('NX').value('downloadUrl').get()) + _('nochamine web site') + '</a></p>'
res = '<div idTransport="applet"><applet code="NxTransportApplet.class" codebase="%s" archive="%s" width="140" height="22"><param name="data" value="%s"/><param name="permissions" value="all-permissions"/></applet></div>' % (codebase, '1', data )
res += '<div>' + msg + '</div>'
return res
def getHtmlComponent(module, componentId):
dict = { '1' : ['nxtransport.jar', 'application/java-archive' ]}
dct = { '1' : ['nxtransport.jar', 'application/java-archive' ]}
if dict.has_key(componentId) == False:
if dct.has_key(componentId) == False:
return ['text/plain', 'no component']
fname = os.path.dirname(sys.modules[module].__file__) + '/applet/' + dict[componentId][0]
fname = os.path.dirname(sys.modules[module].__file__) + '/applet/' + dct[componentId][0]
logger.debug('Loading component {0} from {1}'.format(componentId, fname))
f = open(fname, 'rb')
data = f.read()
f.close()
return [ dict[componentId][1], data ]
return [ dct[componentId][1], data ]

View File

@ -156,6 +156,9 @@ class RDPTransport(Transport):
# We use helper to keep this clean
username = user.getUsernameForAuth()
prefs = user.prefs('rdp')
if self._fixedName is not '':
username = self._fixedName
proc = username.split('@')
if len(proc) > 1:
@ -163,14 +166,18 @@ class RDPTransport(Transport):
else:
domain = ''
username = proc[0]
if self._fixedName is not '':
username = self._fixedName
if self._fixedPassword is not '':
password = self._fixedPassword
if self._fixedDomain is not '':
domain = self._fixedDomain;
if self._useEmptyCreds is True:
username, password, domain = '','',''
if domain != '':
if domain.find('.') == -1: # Dotter domain form
username = username + '@' + domain
domain = ''
width, height = CommonPrefs.getWidthHeight(prefs)
depth = CommonPrefs.getDepth(prefs)

View File

@ -145,6 +145,9 @@ class TSRDPTransport(Transport):
# We use helper to keep this clean
username = user.getUsernameForAuth()
prefs = user.prefs('rdp')
if self._fixedName is not '':
username = self._fixedName
proc = username.split('@')
if len(proc) > 1:
@ -152,8 +155,6 @@ class TSRDPTransport(Transport):
else:
domain = ''
username = proc[0]
if self._fixedName is not '':
username = self._fixedName
if self._fixedPassword is not '':
password = self._fixedPassword
if self._fixedDomain is not '':
@ -161,6 +162,11 @@ class TSRDPTransport(Transport):
if self._useEmptyCreds is True:
username, password, domain = '','',''
if domain != '':
if domain.find('.') == -1: # Dotter domain form
username = username + '@' + domain
domain = ''
width, height = CommonPrefs.getWidthHeight(prefs)
depth = CommonPrefs.getDepth(prefs)
cache = Cache('pam')

View File

@ -79,7 +79,7 @@ def generateHtmlForRdp(transport, idUserService, idTransport, os, ip, port, user
data.append('tun:' + extra['tun'])
data = scramble('\t'.join(data))
res = '<div id="applet"><applet code="RdpApplet.class" codebase="%s" archive="%s" width="200" height="22"><param name="data" value="%s"/></applet></div>' % (codebase, '1', data )
res = '<div id="applet"><applet code="RdpApplet.class" codebase="%s" archive="%s" width="200" height="22"><param name="data" value="%s"/><param name="permissions" value="all-permissions"/></applet></div>' % (codebase, '1', data )
if isMac is True:
res += ('<div><p>' + _('In order to use this service, you should first install CoRD.') + '</p>'
'<p>' + _('You can obtain it from') + ' <a href="http://cord.sourceforge.net/">' + _('CoRD Website') + '</a></p>'

View File

@ -196,7 +196,7 @@ class TSNXTransport(Transport):
# Fix username/password acording to os manager
username, password = userService.processUserPassword(username, password)
return generateHtmlForNX(self, idUserService, idTransport, username, password, extra)
return generateHtmlForNX(self, idUserService, idTransport, os, username, password, extra)
def getHtmlComponent(self, theId, os, componentId):
# We use helper to keep this clean

View File

@ -33,10 +33,14 @@
from uds.core.managers.UserPrefsManager import UserPrefsManager, CommonPrefs
from uds.core.managers.DownloadsManager import DownloadsManager
from uds.core.util.Config import Config
from TSNXTransport import TSNXTransport
from django.utils.translation import ugettext_noop as _
import os.path, sys
Config.section('NX').value('downloadUrl', 'http://www.nomachine.com/download-3').get()
Config.section('NX').value('downloadUrlMACOS', 'http://opennx.net/download.html').get()
UserPrefsManager.manager().registerPrefs('nx', _('NX Protocol'),
[
CommonPrefs.screenSizePref

View File

@ -32,6 +32,9 @@
'''
from django.core.urlresolvers import reverse
from uds.core.util.Config import Config
from uds.core.util import OsDetector
import logging, os, sys
logger = logging.getLogger(__name__)
@ -52,7 +55,8 @@ def simpleScrambler(data):
def generateHtmlForNX(transport, idUserService, idTransport, user, password, extra):
def generateHtmlForNX(transport, idUserService, idTransport, os, user, password, extra):
isMac = os['OS'] == OsDetector.Macintosh
applet = reverse('uds.web.views.transcomp', kwargs = { 'idTransport' : idTransport, 'componentId' : '1' })
# Gets the codebase, simply remove last char from applet
codebase = applet[:-1]
@ -71,9 +75,15 @@ def generateHtmlForNX(transport, idUserService, idTransport, user, password, ext
'is:' + idUserService
]
data = simpleScrambler( '\t'.join(data))
res = '<div idTransport="applet"><applet code="NxTunTransportApplet.class" codebase="%s" archive="%s" width="165" height="22"><param name="data" value="%s"/></applet></div>' % (codebase, '1', data )
res += '<div><p>In order to use this transport, you need to install first nomachine nx client version 3.5.x</p>'
res += '<p>you can obtain it for your platform from <a href="http://www.nomachine.com/download.php">nochamine web site </a></p></div>'
if isMac is True:
msg = '<p>' + _('In order to use this transport, you need to install first OpenNX Client for mac') + '</p>'
msg += '<p>' + _('You can oibtain it from ') + '<a href="{0}">'.format(Config.section('NX').value('downloadUrlMACOS').get()) + _('OpenNx Website') + '</a></p>'
else:
msg = '<p>' + _('In order to use this transport, you need to install first Nomachine Nx Client version 3.5.x') + '</p>'
msg +='<p>' + _('you can obtain it for your platform from') + '<a href="{0}">'.format(Config.section('NX').value('downloadUrl').get()) + _('nochamine web site') + '</a></p>'
res = '<div idTransport="applet"><applet code="NxTunTransportApplet.class" codebase="%s" archive="%s" width="165" height="22"><param name="data" value="%s"/><param name="permissions" value="all-permissions"/></applet></div>' % (codebase, '1', data )
res += '<div>' + msg + '</div>'
return res

View File

@ -55,7 +55,7 @@ class BaseForm(forms.Form):
class LoginForm(BaseForm):
user = forms.CharField(label=_('Username'), max_length=64)
password = forms.CharField(label=_('Password'), widget=forms.PasswordInput({'title': _('Password')}))
password = forms.CharField(label=_('Password'), widget=forms.PasswordInput({'title': _('Password')}), required=False)
authenticator = forms.ChoiceField(label=_('Authenticator'), choices = ())
java = forms.CharField(widget = forms.HiddenInput())
standard = forms.CharField(widget = forms.HiddenInput(), required=False)

View File

@ -189,6 +189,8 @@ def index(request):
trans.append({ 'id' : scrambleId(request, t.id), 'name' : t.name, 'needsJava' : typeTrans.needsJava })
services.append( {'id' : scrambleId(request, 'd' + str(svr.id)), 'name': svr.name, 'transports' : trans } )
services = sorted(services, key=lambda s: s['name'])
logger.debug('Services: {0}'.format(services))
if len(services) == 1 and GlobalConfig.AUTORUN_SERVICE.get(True) == '1' and len(services[0]['transports']) > 0: