forked from shaba/openuds
Compare commits
21 Commits
master
...
tags/1.2u1
Author | SHA1 | Date | |
---|---|---|---|
|
668578826e | ||
|
646f4fadfb | ||
|
158ac77727 | ||
|
47ea0a3bcb | ||
|
3646c9dec9 | ||
|
d5e71be73c | ||
|
1ea5987975 | ||
|
32ffe5e2d7 | ||
|
add4c58128 | ||
|
6488f0e80d | ||
|
8a3ea8f4c9 | ||
|
bf47f40939 | ||
|
7e8fa876fa | ||
|
dbe7e5187b | ||
|
808dfa5aa0 | ||
|
7a3eccc5ba | ||
|
a3348c9299 | ||
|
f53b8fee61 | ||
|
5047225ea0 | ||
|
44da266276 | ||
|
a7b5b85c05 |
165
.gitignore
vendored
Normal file
165
.gitignore
vendored
Normal 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
11
.project
Normal 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>
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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>'
|
||||
|
@ -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):
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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):
|
||||
|
@ -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')
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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))
|
||||
|
||||
|
@ -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
|
||||
|
Binary file not shown.
@ -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 ]
|
@ -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)
|
||||
|
@ -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')
|
||||
|
Binary file not shown.
Binary file not shown.
@ -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>'
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Binary file not shown.
Binary file not shown.
@ -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
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user