Feature: Added a maintenance mode which locks all other users out
This commit is contained in:
parent
cb7e6e89a5
commit
fdcedb262c
brewman
@ -4,7 +4,7 @@ from sqlalchemy import engine_from_config
|
||||
|
||||
from pyramid.authentication import AuthTktAuthenticationPolicy
|
||||
from pyramid.authorization import ACLAuthorizationPolicy
|
||||
from pyramid.session import UnencryptedCookieSessionFactoryConfig
|
||||
from pyramid.session import SignedCookieSessionFactory
|
||||
from brewman.factories import add_route
|
||||
from brewman.models import initialize_sql
|
||||
from brewman.renderers import json_renderer, CSVRenderer
|
||||
@ -19,7 +19,7 @@ def main(global_config, **settings):
|
||||
engine = engine_from_config(settings, 'sqlalchemy.')
|
||||
initialize_sql(engine)
|
||||
|
||||
session_factory = UnencryptedCookieSessionFactoryConfig('secret')
|
||||
session_factory = SignedCookieSessionFactory('secret')
|
||||
|
||||
authentication_policy = AuthTktAuthenticationPolicy('brewman', timeout=900, reissue_time=90, callback=groupfinder)
|
||||
authorization_policy = ACLAuthorizationPolicy()
|
||||
@ -31,8 +31,6 @@ def main(global_config, **settings):
|
||||
authorization_policy=authorization_policy,
|
||||
session_factory=session_factory
|
||||
)
|
||||
# This changes in pyramid 1.4 to something similar to "config.add_renderer('myjson', JSON(indent=4))"
|
||||
# http://docs.pylonsproject.org/projects/pyramid/en/master/api/renderers.html#pyramid.renderers.JSON
|
||||
config.add_renderer(name='json', factory=json_renderer)
|
||||
config.add_renderer(name='csv', factory=CSVRenderer)
|
||||
|
||||
@ -99,6 +97,7 @@ def main(global_config, **settings):
|
||||
|
||||
config.add_route('settings', '/Settings')
|
||||
config.add_route('api_lock_info', '/api/LockInfo')
|
||||
config.add_route('api_maintenance', '/api/Maintenance')
|
||||
|
||||
add_route(config, 'attendance', '/Attendance', has_list=False, variable='date')
|
||||
config.add_route('api_attendance_types', '/api/AttendanceTypes')
|
||||
|
@ -83,7 +83,8 @@ def fixtures(engine):
|
||||
Role('Reconcile', uuid.UUID('a5cb51cb-e38e-4705-84a7-cc1e9a8b866b')),
|
||||
Role('Stock Movement', uuid.UUID('20b707ee-2b59-41ad-be87-76d5fe1efca8')),
|
||||
Role('Purchases', uuid.UUID('cf7019c8-3fd3-45b0-9a42-601029ce5b71')),
|
||||
Role('Dashboard', uuid.UUID('53eecc09-bd06-4890-b6f5-6885dda762d4'))]
|
||||
Role('Dashboard', uuid.UUID('53eecc09-bd06-4890-b6f5-6885dda762d4')),
|
||||
Role('Maintenance', uuid.UUID('770532e4-21de-4712-8a6b-4ff9fd63a503'))]
|
||||
|
||||
for role in roles:
|
||||
DBSession.add(role)
|
||||
|
@ -132,8 +132,23 @@
|
||||
<label class="col-md-2 control-label">Integrity Check</label>
|
||||
|
||||
<div class="col-md-2">
|
||||
<button class="btn btn-block btn-danger" ng-click="checkDb()">Check Database <i
|
||||
<button class="btn btn-block btn-success" ng-click="checkDb()">Check Database <i
|
||||
class="glyphicon glyphicon-certificate"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">Maintenance Mode</label>
|
||||
|
||||
<div class="col-md-2">
|
||||
<button class="btn btn-block btn-danger" ng-click="setMaintenance(true)">Enable <i
|
||||
class="glyphicon glyphicon-eye-close"></i></button>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<button class="btn btn-block btn-success" ng-click="setMaintenance(false)">Disable <i
|
||||
class="glyphicon glyphicon-eye-open"></i></button>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
Maintenance mode is <strong>{{MaintenanceEnabled()}}</strong> by user <strong>{{maintenance.User}}</strong>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
@ -1,7 +1,11 @@
|
||||
'use strict';
|
||||
|
||||
var SettingsController = ['$scope', '$http', 'asDateFilter', '$modal', 'lockInfo', 'Product', function ($scope, $http, asDate, $modal, lockInfo, Product) {
|
||||
var SettingsController = ['$scope', '$http', 'asDateFilter', '$modal', 'lockInfo', 'maintenance', 'Product', function ($scope, $http, asDate, $modal, lockInfo, maintenance, Product) {
|
||||
$scope.lockInfo = lockInfo.data;
|
||||
$scope.maintenance = maintenance.data;
|
||||
$scope.MaintenanceEnabled = function (){
|
||||
return $scope.maintenance.Enabled ? 'Enabled' : 'Disabled';
|
||||
};
|
||||
$scope.rebaseDate = '';
|
||||
$scope.setLockDate = function () {
|
||||
if ($scope.lockInfo.Start.Locked) {
|
||||
@ -110,7 +114,11 @@ var SettingsController = ['$scope', '$http', 'asDateFilter', '$modal', 'lockInfo
|
||||
var resetDate = asDate($scope.resetDate);
|
||||
var stockDate = asDate($scope.stockDate);
|
||||
var qty = Number($scope.qty);
|
||||
$http({method: 'POST', url: '/api/ResetStock/' + $scope.product.ProductID, params: {StockDate: stockDate, ResetDate: resetDate, Quantity: qty}}).
|
||||
$http({
|
||||
method: 'POST',
|
||||
url: '/api/ResetStock/' + $scope.product.ProductID,
|
||||
params: {StockDate: stockDate, ResetDate: resetDate, Quantity: qty}
|
||||
}).
|
||||
success(function () {
|
||||
$scope.toasts.push({Type: 'Success', Message: 'Data rebased!'});
|
||||
}).
|
||||
@ -131,6 +139,17 @@ var SettingsController = ['$scope', '$http', 'asDateFilter', '$modal', 'lockInfo
|
||||
$scope.toasts.push({Type: 'Danger', Message: errorMessage});
|
||||
});
|
||||
};
|
||||
|
||||
$scope.setMaintenance = function (status) {
|
||||
return $http.post('/api/Maintenance', {Enabled: status}).
|
||||
success(function (data) {
|
||||
$scope.maintenance = data;
|
||||
$scope.toasts.push({Type: 'Success', Message: ''});
|
||||
}).
|
||||
error(function (errorMessage) {
|
||||
$scope.toasts.push({Type: 'Danger', Message: errorMessage});
|
||||
});
|
||||
};
|
||||
}];
|
||||
|
||||
SettingsController.resolve = {
|
||||
@ -138,6 +157,11 @@ SettingsController.resolve = {
|
||||
return $http.get('/api/LockInfo', {}).then(function (data) {
|
||||
return data;
|
||||
});
|
||||
}],
|
||||
maintenance: ['$http', function ($http) {
|
||||
return $http.get('/api/Maintenance', {}).then(function (data) {
|
||||
return data;
|
||||
});
|
||||
}]
|
||||
};
|
||||
|
||||
|
@ -1,12 +1,10 @@
|
||||
from pyramid.events import subscriber, NewRequest
|
||||
from pyramid.events import subscriber, NewRequest
|
||||
from pyramid.httpexceptions import HTTPServiceUnavailable
|
||||
from brewman.models.master import DbSetting
|
||||
|
||||
|
||||
@subscriber(NewRequest)
|
||||
def csrf_validation(event):
|
||||
pass
|
||||
# print(event.request.method, event.request.url, event.request.query_string)
|
||||
# if event.request.method == "POST" and not event.request.is_xhr:
|
||||
# token = event.request.POST.get("_csrf")
|
||||
# print('CSRF POST token is ' + token + ' vs Server ' + event.request.session.get_csrf_token())
|
||||
|
||||
# if token is None or token != event.request.session.get_csrf_token():
|
||||
# raise HTTPForbidden('CSRF token is missing or invalid ' + token + ' Original ' + event.request.session.get_csrf_token())
|
||||
def maintenance_mode(event):
|
||||
maintenance = DbSetting.by_name('Maintenance')
|
||||
if maintenance is not None and maintenance.data != event.request.authenticated_userid:
|
||||
raise HTTPServiceUnavailable
|
||||
|
@ -1,11 +1,12 @@
|
||||
import datetime
|
||||
|
||||
import pkg_resources
|
||||
from pyramid.response import FileResponse
|
||||
|
||||
from pyramid.view import view_config
|
||||
import transaction
|
||||
from brewman.models import DBSession
|
||||
|
||||
from brewman.models import DBSession
|
||||
from brewman.models.auth import User
|
||||
from brewman.models.master import DbSetting
|
||||
from brewman.models.validation_exception import TryCatchFunction
|
||||
|
||||
@ -80,3 +81,30 @@ def get_lock_info(request):
|
||||
else:
|
||||
info['Finish']['Date'] = data['Finish']['Date'].strftime('%d-%b-%Y')
|
||||
return info
|
||||
|
||||
|
||||
@view_config(request_method='GET', route_name='api_maintenance', renderer='json', permission='Authenticated')
|
||||
def get_maintenance(request):
|
||||
data = DbSetting.by_name('Maintenance')
|
||||
if data is None:
|
||||
return {'Enabled': False, 'User': ''}
|
||||
user = User.by_id(data.data)
|
||||
return {'Enabled': True, 'User': user.name}
|
||||
|
||||
|
||||
@view_config(request_method='POST', route_name='api_maintenance', renderer='json', permission='Maintenance')
|
||||
@TryCatchFunction
|
||||
def set_maintenance(request):
|
||||
status = request.json_body['Enabled']
|
||||
maintenance = DbSetting.by_name('Maintenance')
|
||||
if status is False and maintenance is not None:
|
||||
DBSession.delete(maintenance)
|
||||
elif status is True and maintenance is None:
|
||||
maintenance = DbSetting(name='Maintenance', data=request.authenticated_userid)
|
||||
DBSession.add(maintenance)
|
||||
elif status is True and maintenance.data != request.authenticated_userid:
|
||||
maintenance.data = request.authenticated_userid
|
||||
transaction.commit()
|
||||
return get_maintenance(request)
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user