improve permissions

This commit is contained in:
Davide Alberani 2016-07-09 17:41:16 +02:00
parent bb3fb40995
commit a27f9b0db9
5 changed files with 34 additions and 20 deletions

View file

@ -5,7 +5,7 @@
<h1>
{{event.title}}
<span ng-if="hasPermission('event|create') && !event._id">{{'New event' | translate}}</span>
&nbsp;<button ng-if="event._id && hasPermission('tickets-all|read')" ng-click="$state.go('event.tickets', {id: event._id})" class="btn btn-success">
&nbsp;<button ng-if="event._id && hasPermission('event:tickets-all|read')" ng-click="$state.go('event.tickets', {id: event._id})" class="btn btn-success">
<span class="fa fa-ticket vcenter"></span>
{{'Tickets' | translate}}
</button>

View file

@ -47,11 +47,11 @@
<p>{{'Begins:' | translate}} {{event['begin-date'] | date:'fullDate'}} {{event['begin-time'] | date:'HH:mm'}}<br/>
{{'Ends:' | translate}} {{event['end-date'] | date:'fullDate' }} {{event['end-time'] | date:'HH:mm'}}</p>
</td>
<td ng-if="hasPermission('tickets-all|read')" class="hcenter">
<td ng-if="hasPermission('event:tickets-all|read')" class="hcenter">
<p><span ng-init="attendeesNr = ((event.tickets || []) | attendeesFilter).length">{{attendeesNr}}</span> / {{((event.tickets || []) | registeredFilter).length}} ({{((attendeesNr / ((event.tickets || []) | registeredFilter).length * 100) || 0).toFixed()}}%)</p>
</td>
<td>
<button ng-if="hasPermission('event:tickets|create')" ng-click="$state.go('event.ticket.new', {id: event._id})" class="btn btn-link fa fa-user-plus" type="button" title="{{'Join this event' | translate}}"></button>
<button ng-if="hasPermission('event:tickets-all|create')" ng-click="$state.go('event.ticket.new', {id: event._id})" class="btn btn-link fa fa-user-plus" type="button" title="{{'Join this event' | translate}}"></button>
<button ng-if="hasPermission('tickets|update')" ng-click="$state.go('event.tickets', {id: event._id})" class="btn btn-link fa fa-list" type="button" title="{{'Manage attendees' | translate}}"></button>
<button ng-if="hasPermission('event|update')" ng-click="$state.go('event.edit', {id: event._id})" type="button" class="btn btn-link fa fa-cog fa-lg" title="{{'Edit' | translate}}"></button>
<button ng-if="hasPermission('event|delete')" ng-click="remove(event._id)" type="button" class="btn btn-link fa fa-trash fa-lg" title="{{'Delete' | translate}}"></button>

View file

@ -312,6 +312,9 @@ eventManControllers.controller('EventTicketsCtrl', ['$scope', '$state', 'Event',
};
$scope._localUpdateTicket = function(ticket) {
if (!$state.is('event.tickets')) {
return;
}
if (!$scope.event.tickets) {
$scope.event.tickets = [];
}
@ -362,19 +365,22 @@ eventManControllers.controller('EventTicketsCtrl', ['$scope', '$state', 'Event',
if (!(data && data._id && data.ticket)) {
return;
}
if (callback) {
callback(data);
}
if (!$state.is('event.tickets')) {
return;
}
var ticket_idx = $scope.event.tickets.findIndex(function(el, idx, array) {
return data._id == el._id;
});
if (ticket_idx == -1) {
$log.warn('unable to find ticket _id ' + _id);
$log.warn('unable to find ticket _id ' + data._id);
return;
}
if ($scope.event.tickets[ticket_idx] != data.ticket) {
$scope.event.tickets[ticket_idx] = data.ticket;
}
if (callback) {
callback(data);
}
if (key === 'attended' && !hideMessage) {
var msg = {};
if (value) {

View file

@ -20,7 +20,7 @@
<span class="fa fa-calendar vcenter"></span>
{{'Edit event' | translate}}
</button>
&nbsp;<button ng-click="$state.go('event.tickets', {id: event._id})" class="btn btn-success" ng-if="event._id && hasPermission('tickets-all|read')">
&nbsp;<button ng-click="$state.go('event.tickets', {id: event._id})" class="btn btn-success" ng-if="event._id && hasPermission('event:tickets-all|read')">
<span class="fa fa-ticket vcenter"></span>
{{'Tickets' | translate}}
</button>

View file

@ -46,9 +46,12 @@ API_VERSION = '1.0'
re_env_key = re.compile('[^A-Z_]+')
re_slashes = re.compile(r'//+')
# Keep track of WebSocket connections.
_ws_clients = {}
def authenticated(method):
"""Decorator to handle authentication."""
"""Decorator to handle forced authentication."""
original_wrapper = tornado.web.authenticated(method)
@tornado.web.functools.wraps(method)
def my_wrapper(self, *args, **kwargs):
@ -85,7 +88,9 @@ class BaseHandler(tornado.web.RequestHandler):
"""Base class for request handlers."""
permissions = {
'event|read': True,
'event:tickets|all': True,
'event:tickets|read': True,
'event:tickets|create': True,
'event:tickets|update': True,
'event:tickets-all|create': True,
'events|read': True,
'users|create': True
@ -228,7 +233,13 @@ class BaseHandler(tornado.web.RequestHandler):
return (False, {})
def build_error(self, message='', status=400):
"""Build and write an error message."""
"""Build and write an error message.
:param message: textual message
:type message: str
:param status: HTTP status code
:type status: int
"""
self.set_status(status)
self.write({'error': True, 'message': message})
@ -250,9 +261,6 @@ class RootHandler(BaseHandler):
self.write(fd.read())
# Keep track of WebSocket connections.
_ws_clients = {}
class CollectionHandler(BaseHandler):
"""Base class for handlers that need to interact with the database backend.
@ -856,7 +864,7 @@ class SettingsHandler(BaseHandler):
"""Handle requests for Settings."""
@gen.coroutine
@authenticated
def get(self, **kwds):
def get(self, **kwargs):
query = self.arguments_tobool()
settings = self.db.query('settings', query)
self.write({'settings': settings})
@ -865,7 +873,7 @@ class SettingsHandler(BaseHandler):
class InfoHandler(BaseHandler):
"""Handle requests for information about the logged in user."""
@gen.coroutine
def get(self, **kwds):
def get(self, **kwargs):
info = {}
user_info = self.current_user_info
if user_info:
@ -879,7 +887,7 @@ class WebSocketEventUpdatesHandler(tornado.websocket.WebSocketHandler):
def _clean_url(self, url):
return re_slashes.sub('/', url)
def open(self, event_id, *args, **kwds):
def open(self, event_id, *args, **kwargs):
logging.debug('WebSocketEventUpdatesHandler.on_open event_id:%s' % event_id)
_ws_clients.setdefault(self._clean_url(self.request.uri), set()).add(self)
logging.debug('WebSocketEventUpdatesHandler.on_open %s clients connected' % len(_ws_clients))
@ -907,7 +915,7 @@ class LoginHandler(RootHandler):
"""Handle user authentication requests."""
@gen.coroutine
def get(self, **kwds):
def get(self, **kwargs):
# show the login page
if self.is_api():
self.set_status(401)
@ -943,7 +951,7 @@ class LoginHandler(RootHandler):
class LogoutHandler(BaseHandler):
"""Handle user logout requests."""
@gen.coroutine
def get(self, **kwds):
def get(self, **kwargs):
# log the user out
logging.info('logout')
self.logout()
@ -1020,7 +1028,7 @@ def run():
template_path=os.path.join(os.path.dirname(__file__), "templates"),
static_path=os.path.join(os.path.dirname(__file__), "static"),
cookie_secret='__COOKIE_SECRET__',
login_url='/#/login',
login_url='/login',
debug=options.debug)
ssl_options = {}
if os.path.isfile(options.ssl_key) and os.path.isfile(options.ssl_cert):