1
0
mirror of https://github.com/dkmstr/openuds.git synced 2025-03-11 00:58:39 +03:00

Lots of new things

* Now we can have a short name for correct visualization of UDS Services
* We now can allow release services
This commit is contained in:
Adolfo Gómez García 2017-10-26 13:35:53 +02:00
parent 22a8933e82
commit c5b9233d4a
14 changed files with 482 additions and 44 deletions

View File

@ -69,7 +69,7 @@ class ServicesPools(ModelHandler):
'actions': ActionsCalendars
}
save_fields = ['name', 'comments', 'tags', 'service_id', 'osmanager_id', 'image_id', 'servicesPoolGroup_id', 'initial_srvs', 'cache_l1_srvs', 'cache_l2_srvs', 'max_srvs', 'show_transports']
save_fields = ['name', 'short_name', 'comments', 'tags', 'service_id', 'osmanager_id', 'image_id', 'servicesPoolGroup_id', 'initial_srvs', 'cache_l1_srvs', 'cache_l2_srvs', 'max_srvs', 'show_transports', 'allow_users_remove']
remove_fields = ['osmanager_id', 'service_id']
table_title = _('Service Pools')
@ -110,6 +110,7 @@ class ServicesPools(ModelHandler):
val = {
'id': item.uuid,
'name': item.name,
'short_name': item.short_name,
'tags': [tag.tag for tag in item.tags.all()],
'parent': item.service.name,
'parent_type': item.service.data_type,
@ -130,6 +131,7 @@ class ServicesPools(ModelHandler):
'user_services_in_preparation': item.userServices.filter(state=State.PREPARING).count(),
'restrained': item.isRestrained(),
'show_transports': item.show_transports,
'allow_users_remove': item.allow_users_remove,
'fallbackAccess': item.fallbackAccess,
'permission': permissions.getEffectivePermission(self._user, item),
'info': Services.serviceInfo(item.service),
@ -147,7 +149,7 @@ class ServicesPools(ModelHandler):
if Service.objects.count() < 1:
raise ResponseError(ugettext('Create at least a service before creating a new service pool'))
g = self.addDefaultFields([], ['name', 'comments', 'tags'])
g = self.addDefaultFields([], ['name', 'short_name', 'comments', 'tags'])
for f in [{
'name': 'service_id',
@ -224,6 +226,13 @@ class ServicesPools(ModelHandler):
'tooltip': ugettext('If active, alternative transports for user will be shown'),
'type': gui.InputField.CHECKBOX_TYPE,
'order': 120,
}, {
'name': 'allow_users_remove',
'value': False,
'label': ugettext('Allow removal by users'),
'tooltip': ugettext('If active, the user will be allowed to remove the service "manually". Be care with this, because the user will have the "poser" to delete it\'s own service'),
'type': gui.InputField.CHECKBOX_TYPE,
'order': 121,
}]:
self.addField(g, f)

View File

@ -54,7 +54,7 @@ import logging
logger = logging.getLogger(__name__)
__updated__ = '2017-02-02'
__updated__ = '2017-10-25'
# a few constants
@ -123,7 +123,7 @@ class BaseModelHandler(Handler):
'label': _('Tags'),
'type': 'taglist',
'tooltip': _('Tags for this element'),
'order': 0 - 101,
'order': 0 - 105,
})
if 'name' in flds:
self.addField(gui, {
@ -134,13 +134,23 @@ class BaseModelHandler(Handler):
'tooltip': _('Name of this element'),
'order': 0 - 100,
})
if 'short_name' in flds:
self.addField(gui, {
'name': 'short_name',
'type': 'text',
'label': _('Short name'),
'tooltip': _('Short name for user service visualization'),
'required': False,
'length': 16,
'order': 0 - 95,
})
if 'comments' in flds:
self.addField(gui, {
'name': 'comments',
'label': _('Comments'),
'tooltip': _('Comments for this element'),
'length': 256,
'order': 0 - 99,
'order': 0 - 90,
})
if 'priority' in flds:
self.addField(gui, {
@ -151,7 +161,7 @@ class BaseModelHandler(Handler):
'required': True,
'value': 1,
'length': 4,
'order': 0 - 97,
'order': 0 - 85,
})
if 'small_name' in flds:
self.addField(gui, {
@ -161,7 +171,7 @@ class BaseModelHandler(Handler):
'tooltip': _('Label for this element'),
'required': True,
'length': 128,
'order': 0 - 96,
'order': 0 - 80,
})
return gui

View File

@ -51,7 +51,7 @@ import requests
import json
import logging
__updated__ = '2017-10-16'
__updated__ = '2017-10-26'
logger = logging.getLogger(__name__)
traceLogger = logging.getLogger('traceLog')
@ -458,13 +458,12 @@ class UserServiceManager(object):
uService.setState(State.ERROR)
return
def getService(self, user, srcIp, idService, idTransport, doTest=True):
'''
Get service info from
'''
def locateUserService(self, user, idService, create=False):
kind, idService = idService[0], idService[1:]
logger.debug('Kind of service: {0}, idService: {1}'.format(kind, idService))
userService = None
if kind == 'A': # This is an assigned service
logger.debug('Getting A service {}'.format(idService))
userService = UserService.objects.get(uuid=idService)
@ -474,10 +473,21 @@ class UserServiceManager(object):
# We first do a sanity check for this, if the user has access to this service
# If it fails, will raise an exception
ds.validateUser(user)
# Now we have to locate an instance of the service, so we can assign it to user.
userService = self.getAssignationForUser(ds, user)
if create: # getAssignation, if no assignation is found, tries to create one
userService = self.getAssignationForUser(ds, user)
else: # Sometimes maybe we only need to locate the existint user service
userService = self.getExistingAssignationForUser(ds, user)
logger.debug('Found service: {0}'.format(userService))
return userService
def getService(self, user, srcIp, idService, idTransport, doTest=True):
'''
Get service info from
'''
userService = self.locateUserService(user, idService, create=True)
if userService.isInMaintenance() is True:
raise ServiceInMaintenanceMode()

View File

@ -46,9 +46,21 @@ class XUACompatibleMiddleware(object):
return response
class RedirectMiddleware(object):
NO_REDIRECT = [
'rest',
'pam',
'guacamole',
]
def process_request(self, request):
full_path = request.get_full_path()
if GlobalConfig.REDIRECT_TO_HTTPS.getBool() and request.is_secure() is False and full_path[:6] != '/rest/':
redirect = True
for nr in RedirectMiddleware.NO_REDIRECT:
if full_path.startswith('/' + nr):
redirect = False
break
if GlobalConfig.REDIRECT_TO_HTTPS.getBool() and request.is_secure() is False and redirect:
if request.method == 'POST':
url = request.build_absolute_uri(GlobalConfig.LOGIN_URL.get())
else:
@ -56,3 +68,7 @@ class RedirectMiddleware(object):
url = url.replace('http://', 'https://')
return HttpResponseRedirect(url)
@staticmethod
def registerException(path):
RedirectMiddleware.NO_REDIRECT.append(path)

View File

@ -34,7 +34,6 @@ from __future__ import unicode_literals
from django.conf.urls import patterns
urlpatterns = patterns(__package__,
(r'^guacamole/(?P<tunnelId>.+)$', 'views.guacamole'),
)

View File

@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.9 on 2017-10-25 14:05
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('uds', '0023_transport_allowed_oss'),
]
operations = [
migrations.AddField(
model_name='deployedservice',
name='allow_users_remove',
field=models.BooleanField(default=False),
),
migrations.AddField(
model_name='deployedservice',
name='short_name',
field=models.CharField(default='', max_length=32),
),
]

View File

@ -60,8 +60,9 @@ from uds.core.util.calendar import CalendarChecker
from datetime import datetime, timedelta
import logging
import pickle
import six
__updated__ = '2017-01-23'
__updated__ = '2017-10-25'
logger = logging.getLogger(__name__)
@ -73,6 +74,7 @@ class DeployedService(UUIDModel, TaggingMixin):
'''
# pylint: disable=model-missing-unicode
name = models.CharField(max_length=128, default='')
short_name = models.CharField(max_length=32, default='')
comments = models.CharField(max_length=256, default='')
service = models.ForeignKey(Service, null=True, blank=True, related_name='deployedServices')
osmanager = models.ForeignKey(OSManager, null=True, blank=True, related_name='deployedServices')
@ -81,6 +83,7 @@ class DeployedService(UUIDModel, TaggingMixin):
state = models.CharField(max_length=1, default=states.servicePool.ACTIVE, db_index=True)
state_date = models.DateTimeField(default=NEVER)
show_transports = models.BooleanField(default=True)
allow_users_remove = models.BooleanField(default=False)
image = models.ForeignKey(Image, null=True, blank=True, related_name='deployedServices', on_delete=models.SET_NULL)
servicesPoolGroup = models.ForeignKey(ServicesPoolGroup, null=True, blank=True, related_name='servicesPools', on_delete=models.SET_NULL)
@ -164,6 +167,13 @@ class DeployedService(UUIDModel, TaggingMixin):
def is_meta(self):
return self.meta_pools.count() == 0
@property
def visual_name(self):
logger.debug("SHORT: {} {} {}".format(self.short_name, self.short_name is not None, self.name))
if self.short_name is not None and six.text_type(self.short_name).strip() != '':
return six.text_type(self.short_name)
return six.text_type(self.name)
def isRestrained(self):
'''
Maybe this deployed service is having problems, and that may block some task in some

View File

@ -55,7 +55,7 @@ from uds.models.Util import getSqlDatetime
import logging
__updated__ = '2017-09-29'
__updated__ = '2017-10-26'
logger = logging.getLogger(__name__)
@ -394,7 +394,7 @@ class UserService(UUIDModel):
def release(self):
'''
A much more convenient method that "remove"
A much more convenient method name that "remove" (i think :) )
'''
self.remove()

View File

@ -1,13 +1,13 @@
/*!
* Font Awesome 4.4.0 by @davegandy - http://fontawesome.io - @fontawesome
* Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome
* License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
*/
/* FONT PATH
* -------------------------- */
@font-face {
font-family: 'FontAwesome';
src: url('../fonts/fontawesome-webfont.eot?v=4.4.0');
src: url('../fonts/fontawesome-webfont.eot?#iefix&v=4.4.0') format('embedded-opentype'), url('../fonts/fontawesome-webfont.woff2?v=4.4.0') format('woff2'), url('../fonts/fontawesome-webfont.woff?v=4.4.0') format('woff'), url('../fonts/fontawesome-webfont.ttf?v=4.4.0') format('truetype'), url('../fonts/fontawesome-webfont.svg?v=4.4.0#fontawesomeregular') format('svg');
src: url('../fonts/fontawesome-webfont.eot?v=4.7.0');
src: url('../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'), url('../fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'), url('../fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'), url('../fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'), url('../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg');
font-weight: normal;
font-style: normal;
}
@ -118,31 +118,31 @@
}
}
.fa-rotate-90 {
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1);
-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";
-webkit-transform: rotate(90deg);
-ms-transform: rotate(90deg);
transform: rotate(90deg);
}
.fa-rotate-180 {
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2);
-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";
-webkit-transform: rotate(180deg);
-ms-transform: rotate(180deg);
transform: rotate(180deg);
}
.fa-rotate-270 {
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3);
-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";
-webkit-transform: rotate(270deg);
-ms-transform: rotate(270deg);
transform: rotate(270deg);
}
.fa-flip-horizontal {
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);
-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";
-webkit-transform: scale(-1, 1);
-ms-transform: scale(-1, 1);
transform: scale(-1, 1);
}
.fa-flip-vertical {
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);
-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";
-webkit-transform: scale(1, -1);
-ms-transform: scale(1, -1);
transform: scale(1, -1);
@ -1383,7 +1383,7 @@
.fa-digg:before {
content: "\f1a6";
}
.fa-pied-piper:before {
.fa-pied-piper-pp:before {
content: "\f1a7";
}
.fa-pied-piper-alt:before {
@ -1509,6 +1509,7 @@
content: "\f1ce";
}
.fa-ra:before,
.fa-resistance:before,
.fa-rebel:before {
content: "\f1d0";
}
@ -1831,6 +1832,7 @@
content: "\f23e";
}
.fa-battery-4:before,
.fa-battery:before,
.fa-battery-full:before {
content: "\f240";
}
@ -2024,3 +2026,312 @@
.fa-fonticons:before {
content: "\f280";
}
.fa-reddit-alien:before {
content: "\f281";
}
.fa-edge:before {
content: "\f282";
}
.fa-credit-card-alt:before {
content: "\f283";
}
.fa-codiepie:before {
content: "\f284";
}
.fa-modx:before {
content: "\f285";
}
.fa-fort-awesome:before {
content: "\f286";
}
.fa-usb:before {
content: "\f287";
}
.fa-product-hunt:before {
content: "\f288";
}
.fa-mixcloud:before {
content: "\f289";
}
.fa-scribd:before {
content: "\f28a";
}
.fa-pause-circle:before {
content: "\f28b";
}
.fa-pause-circle-o:before {
content: "\f28c";
}
.fa-stop-circle:before {
content: "\f28d";
}
.fa-stop-circle-o:before {
content: "\f28e";
}
.fa-shopping-bag:before {
content: "\f290";
}
.fa-shopping-basket:before {
content: "\f291";
}
.fa-hashtag:before {
content: "\f292";
}
.fa-bluetooth:before {
content: "\f293";
}
.fa-bluetooth-b:before {
content: "\f294";
}
.fa-percent:before {
content: "\f295";
}
.fa-gitlab:before {
content: "\f296";
}
.fa-wpbeginner:before {
content: "\f297";
}
.fa-wpforms:before {
content: "\f298";
}
.fa-envira:before {
content: "\f299";
}
.fa-universal-access:before {
content: "\f29a";
}
.fa-wheelchair-alt:before {
content: "\f29b";
}
.fa-question-circle-o:before {
content: "\f29c";
}
.fa-blind:before {
content: "\f29d";
}
.fa-audio-description:before {
content: "\f29e";
}
.fa-volume-control-phone:before {
content: "\f2a0";
}
.fa-braille:before {
content: "\f2a1";
}
.fa-assistive-listening-systems:before {
content: "\f2a2";
}
.fa-asl-interpreting:before,
.fa-american-sign-language-interpreting:before {
content: "\f2a3";
}
.fa-deafness:before,
.fa-hard-of-hearing:before,
.fa-deaf:before {
content: "\f2a4";
}
.fa-glide:before {
content: "\f2a5";
}
.fa-glide-g:before {
content: "\f2a6";
}
.fa-signing:before,
.fa-sign-language:before {
content: "\f2a7";
}
.fa-low-vision:before {
content: "\f2a8";
}
.fa-viadeo:before {
content: "\f2a9";
}
.fa-viadeo-square:before {
content: "\f2aa";
}
.fa-snapchat:before {
content: "\f2ab";
}
.fa-snapchat-ghost:before {
content: "\f2ac";
}
.fa-snapchat-square:before {
content: "\f2ad";
}
.fa-pied-piper:before {
content: "\f2ae";
}
.fa-first-order:before {
content: "\f2b0";
}
.fa-yoast:before {
content: "\f2b1";
}
.fa-themeisle:before {
content: "\f2b2";
}
.fa-google-plus-circle:before,
.fa-google-plus-official:before {
content: "\f2b3";
}
.fa-fa:before,
.fa-font-awesome:before {
content: "\f2b4";
}
.fa-handshake-o:before {
content: "\f2b5";
}
.fa-envelope-open:before {
content: "\f2b6";
}
.fa-envelope-open-o:before {
content: "\f2b7";
}
.fa-linode:before {
content: "\f2b8";
}
.fa-address-book:before {
content: "\f2b9";
}
.fa-address-book-o:before {
content: "\f2ba";
}
.fa-vcard:before,
.fa-address-card:before {
content: "\f2bb";
}
.fa-vcard-o:before,
.fa-address-card-o:before {
content: "\f2bc";
}
.fa-user-circle:before {
content: "\f2bd";
}
.fa-user-circle-o:before {
content: "\f2be";
}
.fa-user-o:before {
content: "\f2c0";
}
.fa-id-badge:before {
content: "\f2c1";
}
.fa-drivers-license:before,
.fa-id-card:before {
content: "\f2c2";
}
.fa-drivers-license-o:before,
.fa-id-card-o:before {
content: "\f2c3";
}
.fa-quora:before {
content: "\f2c4";
}
.fa-free-code-camp:before {
content: "\f2c5";
}
.fa-telegram:before {
content: "\f2c6";
}
.fa-thermometer-4:before,
.fa-thermometer:before,
.fa-thermometer-full:before {
content: "\f2c7";
}
.fa-thermometer-3:before,
.fa-thermometer-three-quarters:before {
content: "\f2c8";
}
.fa-thermometer-2:before,
.fa-thermometer-half:before {
content: "\f2c9";
}
.fa-thermometer-1:before,
.fa-thermometer-quarter:before {
content: "\f2ca";
}
.fa-thermometer-0:before,
.fa-thermometer-empty:before {
content: "\f2cb";
}
.fa-shower:before {
content: "\f2cc";
}
.fa-bathtub:before,
.fa-s15:before,
.fa-bath:before {
content: "\f2cd";
}
.fa-podcast:before {
content: "\f2ce";
}
.fa-window-maximize:before {
content: "\f2d0";
}
.fa-window-minimize:before {
content: "\f2d1";
}
.fa-window-restore:before {
content: "\f2d2";
}
.fa-times-rectangle:before,
.fa-window-close:before {
content: "\f2d3";
}
.fa-times-rectangle-o:before,
.fa-window-close-o:before {
content: "\f2d4";
}
.fa-bandcamp:before {
content: "\f2d5";
}
.fa-grav:before {
content: "\f2d6";
}
.fa-etsy:before {
content: "\f2d7";
}
.fa-imdb:before {
content: "\f2d8";
}
.fa-ravelry:before {
content: "\f2d9";
}
.fa-eercast:before {
content: "\f2da";
}
.fa-microchip:before {
content: "\f2db";
}
.fa-snowflake-o:before {
content: "\f2dc";
}
.fa-superpowers:before {
content: "\f2dd";
}
.fa-wpexplorer:before {
content: "\f2de";
}
.fa-meetup:before {
content: "\f2e0";
}
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
border: 0;
}
.sr-only-focusable:active,
.sr-only-focusable:focus {
position: static;
width: auto;
height: auto;
margin: 0;
overflow: visible;
clip: auto;
}

File diff suppressed because one or more lines are too long

View File

@ -39,11 +39,18 @@
data-href="{{ trans.link }}"
data-href-alt="{% url 'uds.web.views.client_downloads' %}">
<div class="service-image">
<img class="se-agranda" src="{% url "uds.web.views.serviceImage" idImage=ser.imageId %}" />
<img {% if ser.name != ser.visual_name %}class="with-tooltip" data-content="{{ser.name|capfirst}}"{% endif %} class="se-agranda" src="{% url "uds.web.views.serviceImage" idImage=ser.imageId %}" />
</div>
<span {% if ser.name|length > 16 %}class="with-tooltip" data-content="{{ser.name|capfirst}}"{% endif %}{% if ser.show_transports and numTransports > 1 %} style="width: 80%;"{% endif %}>{{ ser.name|capfirst|truncatechars:16 }}</span>
{% if ser.show_transports and numTransports > 1 %}
<span class="gear"><span class="fa fa-gear fa-spin"> </span></span>
<span {% if ser.show_transports and numTransports > 1 %} style="width: 130px;"{% endif %}>{{ ser.visual_name|capfirst|truncatechars:16 }}</span>
{% if ser.show_transports and numTransports > 1 or ser.allow_users_remove %}
<span class="gear">
{% if ser.show_transports and numTransports > 1 %}
<span class="connection fa fa-gear"> </span>
{% endif %}
{% if ser.allow_users_remove %}
<span data-href="{% url 'Releaser' idService=ser.id %}" class="release fa fa-trash"> </span>
{% endif %}
</span>
{% endif %}
</div>
@ -61,7 +68,6 @@
<li><a class="uds-service-transport" data-href-alt="{% url 'uds.web.views.client_downloads' %}" href="{{ trans.link }}"><img class="transport" src="{% url "uds.web.views.transportIcon" idTrans=trans.id %}" alt="{{ trans.name }}" />{{ trans.name }}</a></li>
{% endfor %}
</ul>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
@ -159,7 +165,7 @@
div.service-container {
display: inline-block;
width: 140px;
width: 162px;
height: 162px;
margin: 0px 8px 24px 8px;
}
@ -167,7 +173,7 @@
div.service {
/*background-color: #FAFAFA;*/
/*background-image: url("{% get_static_prefix %}/img/uds-small-back.png");*/
padding: 6px;
padding: 6px 6px 6px 16px;
/*border: 1px solid #BABABA;
border-radius: 2px;*/
display: block;
@ -263,12 +269,21 @@
div.service > span.gear {
text-align: right;
padding-right: 12px;
padding-right: 8px;
}
span.gear > span.fa {
div.service > span.trash {
text-align: right;
padding-right: 24px;
}
span.gear > span.connection {
cursor: zoom-in;
}
span.gear > span.release {
cursor: cell;
}
</style>
{% endblock %}
@ -345,13 +360,23 @@
return false;
})
$('div.service:not(.maintenance, .notaccesible) > span.gear > span.fa').on("click", function (event) {
$('div.service:not(.maintenance, .notaccesible) > span.gear > span.connection').on("click", function (event) {
event.stopPropagation();
event.preventDefault();
$(this).parent().parent().next().modal();
return false;
});
$('div.service:not(.maintenance, .notaccesible) > span.gear > span.release').on("click", function (event) {
event.stopPropagation();
event.preventDefault();
if ( confirm("{%trans 'Are you sure that you want to release this service. Its current content will be lost!' %}") ) {
window.location.href = $(this).attr('data-href');
}
return false;
});
$(".maintenance").click( function(event) {
$('#maintenance-dialog').modal({
keyboard: false

View File

@ -69,6 +69,9 @@ urlpatterns = patterns(
# Client access enabler
url(r'^enable/(?P<idService>.+)/(?P<idTransport>.+)$', 'web.views.clientEnabler', name='ClientAccessEnabler'),
# Releaser
url(r'^release/(?P<idService>.+)$', 'web.views.release', name='Releaser'),
# Custom authentication callback
(r'^auth/(?P<authName>.+)', 'web.views.authCallback'),
(r'^authinfo/(?P<authName>.+)', 'web.views.authInfo'),

View File

@ -35,7 +35,7 @@ import logging
from .login import login, logout, customAuth
from .index import index, about
from .prefs import prefs
from .service import transportOwnLink, transportIcon, clientEnabler, serviceImage
from .service import transportOwnLink, transportIcon, clientEnabler, serviceImage, release
from .auth import authCallback, authInfo, ticketAuth
from .download import download
from .client_download import client_downloads, plugin_detection
@ -44,6 +44,6 @@ from ..errors import error
from .images import image
from .file_storage import file_storage
__updated__ = '2016-04-05'
__updated__ = '2017-10-26'
logger = logging.getLogger(__name__)

View File

@ -32,13 +32,15 @@ from __future__ import unicode_literals
from django.utils.translation import ugettext as _
from django.http import HttpResponse, HttpResponseRedirect
from django.core.urlresolvers import reverse
from uds.core.util import log
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.views.decorators.cache import cache_page, never_cache
from uds.core.auths.auth import webLoginRequired, webPassword
from uds.core.managers import userServiceManager, cryptoManager
from uds.models import TicketStore
from uds.models import TicketStore, UserService
from uds.core.ui.images import DEFAULT_IMAGE
from uds.core.ui import theme
from uds.core.util.model import processUuid
@ -54,7 +56,7 @@ import logging
logger = logging.getLogger(__name__)
__updated__ = '2016-03-16'
__updated__ = '2017-10-26'
@webLoginRequired(admin=False)
@ -108,7 +110,6 @@ def serviceImage(request, idImage):
@webLoginRequired(admin=False)
@never_cache
def clientEnabler(request, idService, idTransport):
# Maybe we could even protect this even more by limiting referer to own server /? (just a meditation..)
logger.debug('idService: {}, idTransport: {}'.format(idService, idTransport))
url = ''
@ -152,3 +153,22 @@ def clientEnabler(request, idService, idTransport):
}),
content_type='application/json'
)
@webLoginRequired(admin=False)
@never_cache
def release(request, idService):
logger.debug('ID Service: {}'.format(idService))
userService = userServiceManager().locateUserService(request.user, idService, create=False)
logger.debug('UserSrvice: >{}<'.format(userService))
if userService is not None and userService.deployed_service.allow_users_remove:
log.doLog(
userService.deployed_service,
log.INFO,
"Removing User Service {} as requested by {} from {}".format(userService.friendly_name, request.user.pretty_name, request.ip),
log.WEB
)
userService.release()
return HttpResponseRedirect(reverse('Index'))