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

Start the work over admin interface (Dashboard) in parallel with REST api

This commit is contained in:
Adolfo Gómez 2013-11-12 01:09:17 +00:00
parent 495ab90cc2
commit 81d64162f4
16 changed files with 956 additions and 23 deletions

View File

@ -11,8 +11,11 @@ encoding//src/server/urls.py=utf-8
encoding//src/uds/REST/__init__.py=utf-8
encoding//src/uds/REST/handlers.py=utf-8
encoding//src/uds/REST/methods/authentication.py=utf-8
encoding//src/uds/REST/methods/providers.py=utf-8
encoding//src/uds/REST/processors.py=utf-8
encoding//src/uds/__init__.py=utf-8
encoding//src/uds/admin/urls.py=utf-8
encoding//src/uds/admin/views.py=utf-8
encoding//src/uds/auths/ActiveDirectory/Authenticator.py=utf-8
encoding//src/uds/auths/ActiveDirectory/__init__.py=utf-8
encoding//src/uds/auths/ActiveDirectory_enterprise/Authenticator.py=utf-8
@ -194,6 +197,7 @@ encoding//src/uds/services/Vmware_enterprise/client/Exceptions.py=utf-8
encoding//src/uds/services/Vmware_enterprise/client/Server.py=utf-8
encoding//src/uds/services/Vmware_enterprise/client/Task.py=utf-8
encoding//src/uds/services/__init__.py=utf-8
encoding//src/uds/templatetags/REST.py=utf-8
encoding//src/uds/templatetags/html5.py=utf-8
encoding//src/uds/tests/__init__.py=utf-8
encoding//src/uds/tests/core/__init__.py=utf-8

View File

@ -35,7 +35,7 @@ from django import http
from django.views.generic.base import View
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator
from django.utils.translation import ugettext as _
from django.utils.translation import ugettext as _, activate
from django.conf import settings
from handlers import Handler, HandlerError, AccessDenied
@ -102,12 +102,18 @@ class Dispatcher(View):
for l in settings.LANGUAGES:
if args[-1] == l[0]:
lang = l[0]
activate(lang)
logger.error('Found lang {0}'.format(l))
args = args[:-1]
break
# Intantiate method handler and locate http_method dispatcher
# Instantiate method handler and locate http_method dispatcher
try:
handler = cls(request, full_path, http_method, processor.processParameters(), *args, **kwargs)
# If no lang on request, try to get the one from
if lang is None:
activate(handler.getValue('locale'))
else:
handler.setValue('locale', lang) # Update Locale if request had one
operation = getattr(handler, http_method)
except processors.ParametersException as e:
@ -119,12 +125,13 @@ class Dispatcher(View):
allowedMethods.append(n)
return http.HttpResponseNotAllowed(allowedMethods)
except AccessDenied:
return http.HttpResponseForbidden('method access denied')
return http.HttpResponseForbidden('access denied')
except:
logger.exception('error accessing attribute')
logger.debug('Getting attribute {0} for {1}'.format(http_method, full_path))
return http.HttpResponseServerError('Unexcepected error')
# Invokes the handler's operation, add headers to response and returns
try:
response = processor.getResponse(operation())

View File

@ -53,13 +53,14 @@ class Handler(object):
name = None # If name is not used, name will be the class name in lower case
path = None # Path for this method, so we can do /auth/login, /auth/logout, /auth/auths in a simple way
authenticated = True # By default, all handlers needs authentication
only_admin = False # By default, the methods will be accesible by anyone
needs_admin = False # By default, the methods will be accessible by anyone if nothine else indicated
needs_staff = False # By default, staff
# method names: 'get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace'
def __init__(self, request, path, operation, params, *args, **kwargs):
if self.only_admin:
self.authenticated = True # If only_admin, must also be authenticated
if self.needs_admin:
self.authenticated = True # If needs_admin, must also be authenticated
self._request = request
self._path = path
@ -87,7 +88,10 @@ class Handler(object):
if self._authToken is None:
raise AccessDenied()
if self.only_admin and not self.getValue('is_admin'):
if self.needs_admin and not self.getValue('is_admin'):
raise AccessDenied()
if self.needs_staff and not self.getValue('staff_member'):
raise AccessDenied()
def headers(self):
@ -111,7 +115,9 @@ class Handler(object):
@staticmethod
def storeSessionAuthdata(session, id_auth, username, locale, is_admin, staff_member):
session['REST'] = { 'auth': id_auth, 'username': username, 'locale': locale, 'is_admin': is_admin, 'staff_member': staff_member }
session['REST'] = { 'auth': id_auth, 'username': username,
'locale': locale, 'is_admin': is_admin,
'staff_member': staff_member }
def genAuthToken(self, id_auth, username, locale, is_admin, staf_member):
@ -135,3 +141,11 @@ class Handler(object):
return self._session['REST'].get(key)
except:
return None
def setValue(self, key, value):
try:
self._session['REST'][key] = value
self._session.accessed = True
self._session.save()
except:
pass

View File

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2012 Virtual Cable S.L.
# Copyright (c) 2014 Virtual Cable S.L.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
@ -41,11 +41,11 @@ import logging
logger = logging.getLogger(__name__)
# Enclosed methods under /auth path
class Login(Handler):
path = 'auth'
authenticated = False # By default, all handlers needs authentication
admin_method = False # By default, the methods will be accesible by anyone
path = 'auth'
authenticated = False # Public method
def post(self):
'''
@ -72,6 +72,7 @@ class Login(Handler):
return{'result': 'ok', 'token': self.getAuthToken()}
else:
raise Exception('Invalid credentials')
raise Exception('Invalid Credentials')
except Exception as e:
logger.exception('exception')
return {'result': 'error', 'error': unicode(e)}
@ -80,7 +81,6 @@ class Login(Handler):
class Logout(Handler):
path = 'auth'
authenticated = True # By default, all handlers needs authentication
admin_method = False # By default, the methods will be accesible by anyone
def get(self):
# Remove auth token
@ -90,9 +90,9 @@ class Logout(Handler):
def post(self):
return self.get()
class Auth(Handler):
class Auths(Handler):
path = 'auth'
authenticated = False # By default, all handlers needs authentication
admin_method = False # By default, the methods will be accesible by anyone
def auths(self):
for a in Authenticator.all():

View File

@ -0,0 +1,35 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2014 Virtual Cable S.L.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
'''
@author: Adolfo Gómez, dkmaster at dkmon dot com
'''
from __future__ import unicode_literals
from uds.REST import Handler, HandlerError

View File

View File

@ -0,0 +1,40 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2012 Virtual Cable S.L.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
'''
@author: Adolfo Gómez, dkmaster at dkmon dot com
'''
from django.conf import settings
from django.conf.urls import patterns, include
from uds.core.util.modfinder import loadModulesUrls
from uds import REST
urlpatterns = patterns('uds.admin.views',
(r'^$', 'index'),
)

View File

@ -0,0 +1,62 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) 2014 Virtual Cable S.L.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
'''
@author: Adolfo Gómez, dkmaster at dkmon dot com
'''
from __future__ import unicode_literals
from django.http import HttpResponse, HttpResponseRedirect, HttpResponseForbidden
from django.views.decorators.csrf import csrf_exempt
from django.shortcuts import render_to_response
from django.shortcuts import render
from django.template import RequestContext
from django.utils.translation import ugettext as _
from django.core.urlresolvers import reverse
from uds.core.auths.auth import getIp, webLogin, webLogout, webLoginRequired, authenticate, webPassword, authenticateViaCallback, authLogLogin, authLogLogout
from uds.models import Authenticator, DeployedService, Transport, UserService, Network
from uds.web.forms.LoginForm import LoginForm
from uds.core.managers.UserServiceManager import UserServiceManager
from uds.core.managers.UserPrefsManager import UserPrefsManager
from uds.core.managers.DownloadsManager import DownloadsManager
from uds.core.util.Config import GlobalConfig
from uds.core.util.Cache import Cache
from uds.core.util import OsDetector
from uds.core.util import log
import logging
logger = logging.getLogger(__name__)
@webLoginRequired
def index(request):
if request.user.isStaff() is False:
return HttpResponseForbidden(_('Forbidden'))
return render(request, 'uds/admin/index.html')

View File

@ -223,13 +223,13 @@ def webLogin(request, response, user, password):
Helper function to, once the user is authenticated, store the information at the user session.
@return: Always returns True
'''
from uds.REST import Handler
from uds import REST
user.updateLastAccess()
request.session.clear()
request.session[USER_KEY] = user.id
request.session[PASS_KEY] = CryptoManager.manager().xor(password.encode('utf-8'), request.COOKIES['uds'])
# Ensures that this user will have access througt REST api if logged in through web interface
Handler.storeSessionAuthdata(request.session, user.manager.small_name, user.name, get_language(), user.is_admin, user.staff_member)
REST.Handler.storeSessionAuthdata(request.session, user.manager.small_name, user.name, get_language(), user.is_admin, user.staff_member)
return True

View File

@ -0,0 +1,344 @@
{% extends 'uds/admin/templates/base.html' %}
{% block body %}
<!-- Main -->
<div class="container">
<div class="row">
<div class="col-md-3">
<!-- Left column -->
<a href="#"><strong><i class="glyphicon glyphicon-wrench"></i> Tools</strong></a>
<hr>
<ul class="list-unstyled">
<li class="nav-header"> <a href="#" data-toggle="collapse" data-target="#userMenu">
<h5>Settings <i class="glyphicon glyphicon-chevron-down"></i></h5>
</a>
<ul class="list-unstyled collapse in" id="userMenu">
<li class="active"> <a href="#"><i class="glyphicon glyphicon-home"></i> Home</a></li>
<li><a href="#"><i class="glyphicon glyphicon-envelope"></i> Messages <span class="badge badge-info">4</span></a></li>
<li><a href="#"><i class="glyphicon glyphicon-cog"></i> Options</a></li>
<li><a href="#"><i class="glyphicon glyphicon-comment"></i> Shoutbox</a></li>
<li><a href="#"><i class="glyphicon glyphicon-user"></i> Staff List</a></li>
<li><a href="#"><i class="glyphicon glyphicon-flag"></i> Transactions</a></li>
<li><a href="#"><i class="glyphicon glyphicon-exclamation-sign"></i> Rules</a></li>
<li><a href="#"><i class="glyphicon glyphicon-off"></i> Logout</a></li>
</ul>
</li>
<li class="nav-header"> <a href="#" data-toggle="collapse" data-target="#menu2">
<h5>Reports <i class="glyphicon glyphicon-chevron-right"></i></h5>
</a>
<ul class="list-unstyled collapse" id="menu2">
<li><a href="#">Information &amp; Stats</a>
</li>
<li><a href="#">Views</a>
</li>
<li><a href="#">Requests</a>
</li>
<li><a href="#">Timetable</a>
</li>
<li><a href="#">Alerts</a>
</li>
</ul>
</li>
<li class="nav-header">
<a href="#" data-toggle="collapse" data-target="#menu3">
<h5>Social Media <i class="glyphicon glyphicon-chevron-right"></i></h5>
</a>
<ul class="list-unstyled collapse" id="menu3">
<li><a href="#"><i class="glyphicon glyphicon-circle"></i> Facebook</a></li>
<li><a href="#"><i class="glyphicon glyphicon-circle"></i> Twitter</a></li>
</ul>
</li>
</ul>
<hr>
<a href="#"><strong><i class="glyphicon glyphicon-link"></i> Resources</strong></a>
<hr>
<ul class="nav nav-pills nav-stacked">
<li class="nav-header"></li>
<li><a href="#"><i class="glyphicon glyphicon-list"></i> Layouts &amp; Templates</a></li>
<li><a href="#"><i class="glyphicon glyphicon-briefcase"></i> Toolbox</a></li>
<li><a href="#"><i class="glyphicon glyphicon-link"></i> Widgets</a></li>
<li><a href="#"><i class="glyphicon glyphicon-list-alt"></i> Reports</a></li>
<li><a href="#"><i class="glyphicon glyphicon-book"></i> Pages</a></li>
<li><a href="#"><i class="glyphicon glyphicon-star"></i> Social Media</a></li>
</ul>
<hr>
<ul class="nav nav-stacked">
<li class="active"><a href="http://bootply.com" title="The Bootstrap Playground" target="ext">Playground</a></li>
<li><a href="/tagged/bootstrap-3">Bootstrap 3</a></li>
<li><a href="/61518" title="Bootstrap 3 Panel">Panels</a></li>
<li><a href="/61521" title="Bootstrap 3 Icons">Glypicons</a></li>
<li><a href="/61523" title="Bootstrap 3 ListGroup">List Groups</a></li>
<li><a href="#">GitHub</a></li>
<li><a href="/61518" title="Bootstrap 3 Slider">Carousel</a></li>
<li><a href="/62603">Layout</a></li>
</ul>
<hr>
</div><!-- /col-3 -->
<div class="col-md-9">
<!-- column 2 -->
<a href="#"><strong><i class="glyphicon glyphicon-dashboard"></i> My Dashboard</strong></a>
<hr>
<div class="row">
<div class="col-md-12"><ul class="nav navbar-nav pull-right">
<li><a href="#"><i class="glyphicon glyphicon-cog"></i></a></li>
<li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown"><i class="glyphicon glyphicon-comment"></i><span class="count">3</span></a><ul class="dropdown-menu" role="menu"><li><a href="#">1. Is there a way..</a></li><li><a href="#">2. Hello, admin. I would..</a></li><li><a href="#"><strong>All messages</strong></a></li></ul></li>
<li><a href="#"><i class="glyphicon glyphicon-user"></i></a></li>
<li><a title="Add Widget" data-toggle="modal" href="#addWidgetModal"><span class="glyphicon glyphicon-plus-sign"></span> Add Widget</a></li>
</ul>
</div>
<!-- center left-->
<div class="col-md-6">
<div class="well">Inbox Messages <span class="badge pull-right">3</span></div>
<hr>
<div class="btn-group btn-group-justified">
<a href="#" class="btn btn-primary col-sm-3">
<i class="glyphicon glyphicon-plus"></i><br>
Service
</a>
<a href="#" class="btn btn-primary col-sm-3">
<i class="glyphicon glyphicon-cloud"></i><br>
Cloud
</a>
<a href="#" class="btn btn-primary col-sm-3">
<i class="glyphicon glyphicon-cog"></i><br>
Tools
</a>
<a href="#" class="btn btn-primary col-sm-3">
<i class="glyphicon glyphicon-question-sign"></i><br>
Help
</a>
</div>
<hr>
<div class="panel panel-default">
<div class="panel-heading"><h4>Reports</h4></div>
<div class="panel-body">
<small>Success</small>
<div class="progress">
<div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="72" aria-valuemin="0" aria-valuemax="100" style="width: 72%">
<span class="sr-only">72% Complete</span>
</div>
</div>
<small>Info</small>
<div class="progress">
<div class="progress-bar progress-bar-info" role="progressbar" aria-valuenow="20" aria-valuemin="0" aria-valuemax="100" style="width: 20%">
<span class="sr-only">20% Complete</span>
</div>
</div>
<small>Warning</small>
<div class="progress">
<div class="progress-bar progress-bar-warning" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: 60%">
<span class="sr-only">60% Complete (warning)</span>
</div>
</div>
<small>Danger</small>
<div class="progress">
<div class="progress-bar progress-bar-danger" role="progressbar" aria-valuenow="80" aria-valuemin="0" aria-valuemax="100" style="width: 80%">
<span class="sr-only">80% Complete</span>
</div>
</div>
</div><!--/panel-body-->
</div><!--/panel-->
<hr>
<!--tabs-->
<div class="container">
<ul class="nav nav-tabs" id="myTab">
<li class="active"><a href="#profile" data-toggle="tab">Profile</a></li>
<li><a href="#messages" data-toggle="tab">Messages</a></li>
<li><a href="#settings" data-toggle="tab">Settings</a></li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="profile">
<h4><i class="glyphicon glyphicon-user"></i></h4>
Lorem profile dolor sit amet, consectetur adipiscing elit. Duis pharetra varius quam sit amet vulputate.
<p>Quisque mauris augue, molestie tincidunt condimentum vitae, gravida a libero. Aenean sit amet felis
dolor, in sagittis nisi. Sed ac orci quis tortor imperdiet venenatis. Duis elementum auctor accumsan.
Aliquam in felis sit amet augue.</p>
</div>
<div class="tab-pane" id="messages">
<h4><i class="glyphicon glyphicon-comment"></i></h4>
Message ipsum dolor sit amet, consectetur adipiscing elit. Duis pharetra varius quam sit amet vulputate.
<p>Quisque mauris augue, molestie tincidunt condimentum vitae, gravida a libero. Aenean sit amet felis
dolor, in sagittis nisi. Sed ac orci quis tortor imperdiet venenatis. Duis elementum auctor accumsan.
Aliquam in felis sit amet augue.</p>
</div>
<div class="tab-pane" id="settings">
<h4><i class="glyphicon glyphicon-cog"></i></h4>
Lorem settings dolor sit amet, consectetur adipiscing elit. Duis pharetra varius quam sit amet vulputate.
<p>Quisque mauris augue, molestie tincidunt condimentum vitae, gravida a libero. Aenean sit amet felis
dolor, in sagittis nisi. Sed ac orci quis tortor imperdiet venenatis. Duis elementum auctor accumsan.
Aliquam in felis sit amet augue.</p>
</div>
</div>
</div>
<!--/tabs-->
<hr>
<div class="panel panel-default">
<div class="panel-heading"><h4>New Requests</h4></div>
<div class="panel-body">
<div class="list-group">
<a href="#" class="list-group-item active">Hosting virtual mailbox serv..</a>
<a href="#" class="list-group-item">Dedicated server doesn't..</a>
<a href="#" class="list-group-item">RHEL 6 install on new..</a>
</div>
</div>
</div>
</div><!--/col-->
<div class="col-md-6">
<div class="panel panel-default">
<div class="panel-heading"><h4>Notices</h4></div>
<div class="panel-body">
<div class="alert alert-info">
<button type="button" class="close" data-dismiss="alert">×</button>
This is a dismissable alert.. just sayin'.
</div>
This is a dashboard-style layout that uses Bootstrap 3. You can use this template as a starting point to create something more unique.
<br><br>
Visit the Bootstrap Playground at <a href="http://bootply.com">Bootply</a> to tweak this layout or discover more useful code snippets.
</div>
</div>
<table class="table table-striped">
<thead>
<tr><th>Visits</th><th>ROI</th><th>Source</th></tr>
</thead>
<tbody>
<tr><td>45</td><td>2.45%</td><td>Direct</td></tr>
<tr><td>289</td><td>56.2%</td><td>Referral</td></tr>
<tr><td>98</td><td>25%</td><td>Type</td></tr>
<tr><td>..</td><td>..</td><td>..</td></tr>
<tr><td>..</td><td>..</td><td>..</td></tr>
</tbody>
</table>
<div class="panel panel-default">
<div class="panel-heading">
<div class="panel-title">
<i class="glyphicon glyphicon-wrench pull-right"></i>
<h4>Post Request</h4>
</div>
</div>
<div class="panel-body">
<form class="form form-vertical">
<div class="control-group">
<label>Name</label>
<div class="controls">
<input class="form-control" placeholder="Enter Name" type="text">
</div>
</div>
<div class="control-group">
<label>Message</label>
<div class="controls">
<textarea class="form-control"></textarea>
</div>
</div>
<div class="control-group">
<label>Category</label>
<div class="controls">
<select class="form-control"><option>options</option></select>
</div>
</div>
<div class="control-group">
<label></label>
<div class="controls">
<button type="submit" class="btn btn-primary">
Post
</button>
</div>
</div>
</form>
</div><!--/panel content-->
</div><!--/panel-->
<div class="panel panel-default">
<div class="panel-heading"><div class="panel-title"><h4>Engagement</h4></div></div>
<div class="panel-body">
<div class="col-xs-4 text-center"><img src="http://placehold.it/80/BBBBBB/FFF" class="img-circle img-responsive"></div>
<div class="col-xs-4 text-center"><img src="http://placehold.it/80/EFEFEF/555" class="img-circle img-responsive"></div>
<div class="col-xs-4 text-center"><img src="http://placehold.it/80/EEEEEE/222" class="img-circle img-responsive"></div>
</div>
</div><!--/panel-->
</div><!--/col-span-6-->
</div><!--/row-->
<hr>
<a href="#"><strong><i class="glyphicon glyphicon-comment"></i> Discussions</strong></a>
<hr>
<div class="row">
<div class="col-md-12">
<ul class="list-group">
<li class="list-group-item"><a href="#"><i class="glyphicon glyphicon-flash"></i> <small>(3 mins ago)</small> The 3rd page reports don't contain any links. Does anyone know why..</a></li>
<li class="list-group-item"><a href="#"><i class="glyphicon glyphicon-flash"></i> <small>(1 hour ago)</small> Hi all, I've just post a report that show the relationship betwe..</a></li>
<li class="list-group-item"><a href="#"><i class="glyphicon glyphicon-heart"></i> <small>(2 hrs ago)</small> Paul. That document you posted yesterday doesn't seem to contain the over..</a></li>
<li class="list-group-item"><a href="#"><i class="glyphicon glyphicon-heart-empty"></i> <small>(4 hrs ago)</small> The map service on c243 is down today. I will be fixing the..</a></li>
<li class="list-group-item"><a href="#"><i class="glyphicon glyphicon-heart"></i> <small>(yesterday)</small> I posted a new document that shows how to install the services layer..</a></li>
<li class="list-group-item"><a href="#"><i class="glyphicon glyphicon-flash"></i> <small>(yesterday)</small> ..</a></li>
</ul>
</div>
</div>
</div><!--/col-span-9-->
</div>
</div>
<!-- /Main -->
<footer class="text-center">This Bootstrap 3 dashboard layout is compliments of <a href="http://www.bootply.com/85850"><strong>Bootply.com</strong></a></footer>
<div class="modal" id="addWidgetModal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title">Add Widget</h4>
</div>
<div class="modal-body">
<p>Add a widget stuff here..</p>
</div>
<div class="modal-footer">
<a href="#" data-dismiss="modal" class="btn">Close</a>
<a href="#" class="btn btn-primary">Save changes</a>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dalog -->
</div><!-- /.modal -->
{% endblock %}

View File

@ -0,0 +1,344 @@
{% extends 'uds/admin/templates/base.html' %}
{% block body %}
<!-- Main -->
<div class="container">
<div class="row">
<div class="col-md-3">
<!-- Left column -->
<a href="#"><strong><i class="glyphicon glyphicon-wrench"></i> Tools</strong></a>
<hr>
<ul class="list-unstyled">
<li class="nav-header"> <a href="#" data-toggle="collapse" data-target="#userMenu">
<h5>Settings <i class="glyphicon glyphicon-chevron-down"></i></h5>
</a>
<ul class="list-unstyled collapse in" id="userMenu">
<li class="active"> <a href="#"><i class="glyphicon glyphicon-home"></i> Home</a></li>
<li><a href="#"><i class="glyphicon glyphicon-envelope"></i> Messages <span class="badge badge-info">4</span></a></li>
<li><a href="#"><i class="glyphicon glyphicon-cog"></i> Options</a></li>
<li><a href="#"><i class="glyphicon glyphicon-comment"></i> Shoutbox</a></li>
<li><a href="#"><i class="glyphicon glyphicon-user"></i> Staff List</a></li>
<li><a href="#"><i class="glyphicon glyphicon-flag"></i> Transactions</a></li>
<li><a href="#"><i class="glyphicon glyphicon-exclamation-sign"></i> Rules</a></li>
<li><a href="#"><i class="glyphicon glyphicon-off"></i> Logout</a></li>
</ul>
</li>
<li class="nav-header"> <a href="#" data-toggle="collapse" data-target="#menu2">
<h5>Reports <i class="glyphicon glyphicon-chevron-right"></i></h5>
</a>
<ul class="list-unstyled collapse" id="menu2">
<li><a href="#">Information &amp; Stats</a>
</li>
<li><a href="#">Views</a>
</li>
<li><a href="#">Requests</a>
</li>
<li><a href="#">Timetable</a>
</li>
<li><a href="#">Alerts</a>
</li>
</ul>
</li>
<li class="nav-header">
<a href="#" data-toggle="collapse" data-target="#menu3">
<h5>Social Media <i class="glyphicon glyphicon-chevron-right"></i></h5>
</a>
<ul class="list-unstyled collapse" id="menu3">
<li><a href="#"><i class="glyphicon glyphicon-circle"></i> Facebook</a></li>
<li><a href="#"><i class="glyphicon glyphicon-circle"></i> Twitter</a></li>
</ul>
</li>
</ul>
<hr>
<a href="#"><strong><i class="glyphicon glyphicon-link"></i> Resources</strong></a>
<hr>
<ul class="nav nav-pills nav-stacked">
<li class="nav-header"></li>
<li><a href="#"><i class="glyphicon glyphicon-list"></i> Layouts &amp; Templates</a></li>
<li><a href="#"><i class="glyphicon glyphicon-briefcase"></i> Toolbox</a></li>
<li><a href="#"><i class="glyphicon glyphicon-link"></i> Widgets</a></li>
<li><a href="#"><i class="glyphicon glyphicon-list-alt"></i> Reports</a></li>
<li><a href="#"><i class="glyphicon glyphicon-book"></i> Pages</a></li>
<li><a href="#"><i class="glyphicon glyphicon-star"></i> Social Media</a></li>
</ul>
<hr>
<ul class="nav nav-stacked">
<li class="active"><a href="http://bootply.com" title="The Bootstrap Playground" target="ext">Playground</a></li>
<li><a href="/tagged/bootstrap-3">Bootstrap 3</a></li>
<li><a href="/61518" title="Bootstrap 3 Panel">Panels</a></li>
<li><a href="/61521" title="Bootstrap 3 Icons">Glypicons</a></li>
<li><a href="/61523" title="Bootstrap 3 ListGroup">List Groups</a></li>
<li><a href="#">GitHub</a></li>
<li><a href="/61518" title="Bootstrap 3 Slider">Carousel</a></li>
<li><a href="/62603">Layout</a></li>
</ul>
<hr>
</div><!-- /col-3 -->
<div class="col-md-9">
<!-- column 2 -->
<a href="#"><strong><i class="glyphicon glyphicon-dashboard"></i> My Dashboard</strong></a>
<hr>
<div class="row">
<div class="col-md-12"><ul class="nav navbar-nav pull-right">
<li><a href="#"><i class="glyphicon glyphicon-cog"></i></a></li>
<li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown"><i class="glyphicon glyphicon-comment"></i><span class="count">3</span></a><ul class="dropdown-menu" role="menu"><li><a href="#">1. Is there a way..</a></li><li><a href="#">2. Hello, admin. I would..</a></li><li><a href="#"><strong>All messages</strong></a></li></ul></li>
<li><a href="#"><i class="glyphicon glyphicon-user"></i></a></li>
<li><a title="Add Widget" data-toggle="modal" href="#addWidgetModal"><span class="glyphicon glyphicon-plus-sign"></span> Add Widget</a></li>
</ul>
</div>
<!-- center left-->
<div class="col-md-6">
<div class="well">Inbox Messages <span class="badge pull-right">3</span></div>
<hr>
<div class="btn-group btn-group-justified">
<a href="#" class="btn btn-primary col-sm-3">
<i class="glyphicon glyphicon-plus"></i><br>
Service
</a>
<a href="#" class="btn btn-primary col-sm-3">
<i class="glyphicon glyphicon-cloud"></i><br>
Cloud
</a>
<a href="#" class="btn btn-primary col-sm-3">
<i class="glyphicon glyphicon-cog"></i><br>
Tools
</a>
<a href="#" class="btn btn-primary col-sm-3">
<i class="glyphicon glyphicon-question-sign"></i><br>
Help
</a>
</div>
<hr>
<div class="panel panel-default">
<div class="panel-heading"><h4>Reports</h4></div>
<div class="panel-body">
<small>Success</small>
<div class="progress">
<div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="72" aria-valuemin="0" aria-valuemax="100" style="width: 72%">
<span class="sr-only">72% Complete</span>
</div>
</div>
<small>Info</small>
<div class="progress">
<div class="progress-bar progress-bar-info" role="progressbar" aria-valuenow="20" aria-valuemin="0" aria-valuemax="100" style="width: 20%">
<span class="sr-only">20% Complete</span>
</div>
</div>
<small>Warning</small>
<div class="progress">
<div class="progress-bar progress-bar-warning" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: 60%">
<span class="sr-only">60% Complete (warning)</span>
</div>
</div>
<small>Danger</small>
<div class="progress">
<div class="progress-bar progress-bar-danger" role="progressbar" aria-valuenow="80" aria-valuemin="0" aria-valuemax="100" style="width: 80%">
<span class="sr-only">80% Complete</span>
</div>
</div>
</div><!--/panel-body-->
</div><!--/panel-->
<hr>
<!--tabs-->
<div class="container">
<ul class="nav nav-tabs" id="myTab">
<li class="active"><a href="#profile" data-toggle="tab">Profile</a></li>
<li><a href="#messages" data-toggle="tab">Messages</a></li>
<li><a href="#settings" data-toggle="tab">Settings</a></li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="profile">
<h4><i class="glyphicon glyphicon-user"></i></h4>
Lorem profile dolor sit amet, consectetur adipiscing elit. Duis pharetra varius quam sit amet vulputate.
<p>Quisque mauris augue, molestie tincidunt condimentum vitae, gravida a libero. Aenean sit amet felis
dolor, in sagittis nisi. Sed ac orci quis tortor imperdiet venenatis. Duis elementum auctor accumsan.
Aliquam in felis sit amet augue.</p>
</div>
<div class="tab-pane" id="messages">
<h4><i class="glyphicon glyphicon-comment"></i></h4>
Message ipsum dolor sit amet, consectetur adipiscing elit. Duis pharetra varius quam sit amet vulputate.
<p>Quisque mauris augue, molestie tincidunt condimentum vitae, gravida a libero. Aenean sit amet felis
dolor, in sagittis nisi. Sed ac orci quis tortor imperdiet venenatis. Duis elementum auctor accumsan.
Aliquam in felis sit amet augue.</p>
</div>
<div class="tab-pane" id="settings">
<h4><i class="glyphicon glyphicon-cog"></i></h4>
Lorem settings dolor sit amet, consectetur adipiscing elit. Duis pharetra varius quam sit amet vulputate.
<p>Quisque mauris augue, molestie tincidunt condimentum vitae, gravida a libero. Aenean sit amet felis
dolor, in sagittis nisi. Sed ac orci quis tortor imperdiet venenatis. Duis elementum auctor accumsan.
Aliquam in felis sit amet augue.</p>
</div>
</div>
</div>
<!--/tabs-->
<hr>
<div class="panel panel-default">
<div class="panel-heading"><h4>New Requests</h4></div>
<div class="panel-body">
<div class="list-group">
<a href="#" class="list-group-item active">Hosting virtual mailbox serv..</a>
<a href="#" class="list-group-item">Dedicated server doesn't..</a>
<a href="#" class="list-group-item">RHEL 6 install on new..</a>
</div>
</div>
</div>
</div><!--/col-->
<div class="col-md-6">
<div class="panel panel-default">
<div class="panel-heading"><h4>Notices</h4></div>
<div class="panel-body">
<div class="alert alert-info">
<button type="button" class="close" data-dismiss="alert">×</button>
This is a dismissable alert.. just sayin'.
</div>
This is a dashboard-style layout that uses Bootstrap 3. You can use this template as a starting point to create something more unique.
<br><br>
Visit the Bootstrap Playground at <a href="http://bootply.com">Bootply</a> to tweak this layout or discover more useful code snippets.
</div>
</div>
<table class="table table-striped">
<thead>
<tr><th>Visits</th><th>ROI</th><th>Source</th></tr>
</thead>
<tbody>
<tr><td>45</td><td>2.45%</td><td>Direct</td></tr>
<tr><td>289</td><td>56.2%</td><td>Referral</td></tr>
<tr><td>98</td><td>25%</td><td>Type</td></tr>
<tr><td>..</td><td>..</td><td>..</td></tr>
<tr><td>..</td><td>..</td><td>..</td></tr>
</tbody>
</table>
<div class="panel panel-default">
<div class="panel-heading">
<div class="panel-title">
<i class="glyphicon glyphicon-wrench pull-right"></i>
<h4>Post Request</h4>
</div>
</div>
<div class="panel-body">
<form class="form form-vertical">
<div class="control-group">
<label>Name</label>
<div class="controls">
<input class="form-control" placeholder="Enter Name" type="text">
</div>
</div>
<div class="control-group">
<label>Message</label>
<div class="controls">
<textarea class="form-control"></textarea>
</div>
</div>
<div class="control-group">
<label>Category</label>
<div class="controls">
<select class="form-control"><option>options</option></select>
</div>
</div>
<div class="control-group">
<label></label>
<div class="controls">
<button type="submit" class="btn btn-primary">
Post
</button>
</div>
</div>
</form>
</div><!--/panel content-->
</div><!--/panel-->
<div class="panel panel-default">
<div class="panel-heading"><div class="panel-title"><h4>Engagement</h4></div></div>
<div class="panel-body">
<div class="col-xs-4 text-center"><img src="http://placehold.it/80/BBBBBB/FFF" class="img-circle img-responsive"></div>
<div class="col-xs-4 text-center"><img src="http://placehold.it/80/EFEFEF/555" class="img-circle img-responsive"></div>
<div class="col-xs-4 text-center"><img src="http://placehold.it/80/EEEEEE/222" class="img-circle img-responsive"></div>
</div>
</div><!--/panel-->
</div><!--/col-span-6-->
</div><!--/row-->
<hr>
<a href="#"><strong><i class="glyphicon glyphicon-comment"></i> Discussions</strong></a>
<hr>
<div class="row">
<div class="col-md-12">
<ul class="list-group">
<li class="list-group-item"><a href="#"><i class="glyphicon glyphicon-flash"></i> <small>(3 mins ago)</small> The 3rd page reports don't contain any links. Does anyone know why..</a></li>
<li class="list-group-item"><a href="#"><i class="glyphicon glyphicon-flash"></i> <small>(1 hour ago)</small> Hi all, I've just post a report that show the relationship betwe..</a></li>
<li class="list-group-item"><a href="#"><i class="glyphicon glyphicon-heart"></i> <small>(2 hrs ago)</small> Paul. That document you posted yesterday doesn't seem to contain the over..</a></li>
<li class="list-group-item"><a href="#"><i class="glyphicon glyphicon-heart-empty"></i> <small>(4 hrs ago)</small> The map service on c243 is down today. I will be fixing the..</a></li>
<li class="list-group-item"><a href="#"><i class="glyphicon glyphicon-heart"></i> <small>(yesterday)</small> I posted a new document that shows how to install the services layer..</a></li>
<li class="list-group-item"><a href="#"><i class="glyphicon glyphicon-flash"></i> <small>(yesterday)</small> ..</a></li>
</ul>
</div>
</div>
</div><!--/col-span-9-->
</div>
</div>
<!-- /Main -->
<footer class="text-center">This Bootstrap 3 dashboard layout is compliments of <a href="http://www.bootply.com/85850"><strong>Bootply.com</strong></a></footer>
<div class="modal" id="addWidgetModal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title">Add Widget</h4>
</div>
<div class="modal-body">
<p>Add a widget stuff here..</p>
</div>
<div class="modal-footer">
<a href="#" data-dismiss="modal" class="btn">Close</a>
<a href="#" class="btn btn-primary">Save changes</a>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dalog -->
</div><!-- /.modal -->
{% endblock %}

View File

@ -0,0 +1,71 @@
{% load l10n i18n static html5 compress REST %}{% spaceless %}
{% get_current_language as LANGUAGE_CODE %}
{% get_available_languages as LANGUAGES %}
<!DOCTYPE html>{% endspaceless %}
<html lang='{{LANGUAGE_CODE}}'>
<head>
<title>{% block title %}{% endblock %}</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="robots" content="noindex, nofollow" />
{% block meta %}{% endblock %}
{% block icon %}<link href="{% get_static_prefix %}img/favicon.ico" rel="icon" type="image/x-icon" />{% endblock %}
{% compress css %}
<!-- Bootstrap -->
<link href="{% get_static_prefix %}css/bootstrap.min.css" rel="stylesheet" media="screen">
<link href="{% get_static_prefix %}css/font-awesome.min.css" rel="stylesheet" media="screen">
<link href="{% get_static_prefix %}css/uds-html5.css" rel="stylesheet" media="screen">
<link href="{% get_static_prefix %}css/bootstrap-theme.min.css" rel="stylesheet" media="screen">
<link href="{% get_static_prefix %}css/bootstrap-formhelpers.min.css" rel="stylesheet" media="screen">
<link href="{% get_static_prefix %}css/bootstrap-responsive.min.css" rel="stylesheet" media="screen">
<link href="{% get_static_prefix %}css/bootstrap-switch.css" rel="stylesheet" media="screen">
{% endcompress %}
{% compress css %}
{% block css %}{% endblock %}
{% endcompress %}
</head>
<body>
<!-- Navigation bar -->
{% block menu %}{% include 'uds/html5/snippets/navbar.html' %}{% endblock %}
<!-- End of menu -->
<div class="container">
{% block messages %}
{% if messages %}
{% for message in messages %}
<div class="alert alert-dismissable {{ message.tags }}">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
{{ message }}
</div>
{% endfor %}
{% endif %}
{% endblock %}
<!-- Content -->
{% block body %}{% endblock %}
<!-- End of content -->
</div> <!-- End of container -->
<footer>
{% block footer %}
<div id="vcable"><a href="http://www.virtualcable.es">&copy; 2012-2014 Virtual Cable S.L.</a> </div>
{% endblock %}
</footer>
{% compress js %}
<script src="{% get_static_prefix %}js/jquery-1.10.2.min.js"></script>
<script src="{% get_static_prefix %}js/jquery.cookie.js"></script>
<script src="{% get_static_prefix %}js/bootstrap.min.js"></script>
<script src="{% get_static_prefix %}js/bootstrap-switch.min.js"></script>
<script>
var decimalSeparator = "{{ 1.1|localize|slice:"1:2" }}";
var authToken = "{% auth_token %}";
</script>
{% endcompress %}
{% compress js %}
{% block js %}{% endblock %}
{% endcompress %}
</body>
</html>

View File

@ -21,7 +21,13 @@
<input id="id_language" type="hidden" name="language" value=""/>
<ul class="nav navbar-nav navbar-right">
{% if user.staff_member or user.is_admin %}
<li><a href="{% url "uds.web.views.download" idDownload='' %}">{% trans "Downloads" %}</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><span class="fa fa-bolt"></span> {% trans 'Administration' %}<b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a href="{% url "uds.web.views.download" idDownload='' %}"><span class="fa fa-download"></span> {% trans "Downloads" %}</a></li>
<li><a href="{% url "uds.admin.views.index" %}"><span class="fa fa-dashboard"></span> {% trans "Dashboard" %}</a></li>
</ul>
</li>
{% endif %}
<li><a href="#">{% trans 'About' %}</a></li>
<li class="dropdown">

View File

@ -40,7 +40,7 @@ logger = logging.getLogger(__name__)
register = template.Library()
@register.simple_tag(name=auth_token, takes_context=True)
@register.simple_tag(name='auth_token', takes_context=True)
def auth_token(context):
'''
Returns the authentication token, and also ensures that

View File

@ -57,15 +57,21 @@ urlpatterns = patterns('uds',
(r'^i18n/', include('django.conf.urls.i18n')),
# Downloadables
(r'^download/(?P<idDownload>.*)$', 'web.views.download'),
# XMLRPC Processor
(r'^xmlrpc$', 'xmlrpc.views.xmlrpc'),
# Custom authentication callback
(r'^auth/(?P<authName>.+)', 'web.views.authCallback'),
(r'^authJava/(?P<idAuth>.+)/(?P<hasJava>.*)$', 'web.views.authJava'),
(r'^authinfo/(?P<authName>.+)', 'web.views.authInfo'),
(r'^about', 'web.views.about'),
# XMLRPC Processor
(r'^xmlrpc$', 'xmlrpc.views.xmlrpc'),
# REST Api
(r'^rest/(?P<arguments>.*)$', REST.Dispatcher.as_view()),
# Web admin GUI
(r'^adm/', include('uds.admin.urls')),
)
# Append urls from special dispatcher
# Append urls from special dispatchers
urlpatterns += loadModulesUrls()

View File

@ -415,7 +415,7 @@ def download(request, idDownload):
Downloadables management
'''
if request.user.isStaff() is False:
return HttpResponseForbidden();
return HttpResponseForbidden(_('Forbidden'))
if idDownload == '':
files = [ { 'id' : key, 'name' : val['name'], 'comment' : _(val['comment']) } for key, val in DownloadsManager.manager().getDownloadables().items() ]