Worked on startup process.

- fix group view on reload
This commit is contained in:
FinnStutzenstein 2017-01-14 13:02:26 +01:00 committed by Emanuel Schütze
parent 481a36501f
commit a6d1eeb9c3
14 changed files with 157 additions and 182 deletions

View File

@ -95,8 +95,7 @@ Other:
- Added new caching system with support for Redis. - Added new caching system with support for Redis.
- Support https as websocket protocol (wss). - Support https as websocket protocol (wss).
- Added migration path from 2.0. - Added migration path from 2.0.
- Add an api for apps to send data when the websocket connection is established. - Accelerated startup process (send all data to the client after login).
- Used this api for all models expect of users to send all data to the client.
Version 2.0 (2016-04-18) Version 2.0 (2016-04-18)

View File

@ -129,6 +129,25 @@ img {
margin: 0 auto 0 auto; margin: 0 auto 0 auto;
} }
#startup-overlay {
display: table;
background-color: #fff;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1000;
}
#startup-overlay h1 {
font-size: 56px;
text-align: center;
}
#startup-overlay > div {
display: table-cell;
vertical-align: middle;
}
/** Header **/ /** Header **/
#header { #header {
float: left; float: left;
@ -138,12 +157,6 @@ img {
color: #999; color: #999;
} }
#header div.unconnected {
border: 1px solid red;
position: fixed;
width: 100%;
z-index: 1000;
}
#header a.headerlink { #header a.headerlink {
text-decoration: none; text-decoration: none;
} }

View File

@ -53,13 +53,12 @@ angular.module('OpenSlidesApp.core', [
.factory('autoupdate', [ .factory('autoupdate', [
'DS', 'DS',
'$rootScope',
'REALM', 'REALM',
'ProjectorID', 'ProjectorID',
function (DS, $rootScope, REALM, ProjectorID) { '$q',
function (DS, REALM, ProjectorID, $q) {
var socket = null; var socket = null;
var recInterval = null; var recInterval = null;
$rootScope.connected = false;
var websocketProtocol; var websocketProtocol;
if (location.protocol == 'https:') { if (location.protocol == 'https:') {
@ -79,6 +78,8 @@ angular.module('OpenSlidesApp.core', [
var Autoupdate = {}; var Autoupdate = {};
Autoupdate.messageReceivers = []; Autoupdate.messageReceivers = [];
// We use later a promise to defer the first message of the established ws connection.
Autoupdate.firstMessageDeferred = $q.defer();
Autoupdate.onMessage = function (receiver) { Autoupdate.onMessage = function (receiver) {
Autoupdate.messageReceivers.push(receiver); Autoupdate.messageReceivers.push(receiver);
}; };
@ -90,11 +91,7 @@ angular.module('OpenSlidesApp.core', [
Autoupdate.newConnect = function () { Autoupdate.newConnect = function () {
socket = new WebSocket(websocketProtocol + '//' + location.host + websocketPath); socket = new WebSocket(websocketProtocol + '//' + location.host + websocketPath);
clearInterval(recInterval); clearInterval(recInterval);
socket.onopen = function () {
$rootScope.connected = true;
};
socket.onclose = function () { socket.onclose = function () {
$rootScope.connected = false;
socket = null; socket = null;
recInterval = setInterval(function () { recInterval = setInterval(function () {
Autoupdate.newConnect(); Autoupdate.newConnect();
@ -104,12 +101,50 @@ angular.module('OpenSlidesApp.core', [
_.forEach(Autoupdate.messageReceivers, function (receiver) { _.forEach(Autoupdate.messageReceivers, function (receiver) {
receiver(event.data); receiver(event.data);
}); });
// The first message is done: resolve the promise.
// TODO: check whether the promise is already resolved.
Autoupdate.firstMessageDeferred.resolve();
}; };
}; };
return Autoupdate; return Autoupdate;
} }
]) ])
.factory('operator', [
'User',
'Group',
function (User, Group) {
var operator = {
user: null,
perms: [],
isAuthenticated: function () {
return !!this.user;
},
setUser: function(user_id, user_data) {
if (user_id && user_data) {
operator.user = User.inject(user_data);
operator.perms = operator.user.getPerms();
} else {
operator.user = null;
operator.perms = Group.get(1).permissions;
}
},
// Returns true if the operator has at least one perm of the perms-list.
hasPerms: function(perms) {
if (typeof perms === 'string') {
perms = perms.split(' ');
}
return _.intersection(perms, operator.perms).length > 0;
},
// Returns true if the operator is a member of group.
isInGroup: function(group) {
return _.indexOf(operator.user.groups_id, group.id) > -1;
},
};
return operator;
}
])
// gets all in OpenSlides available languages // gets all in OpenSlides available languages
.factory('Languages', [ .factory('Languages', [
'gettext', 'gettext',
@ -227,7 +262,7 @@ angular.module('OpenSlidesApp.core', [
var deletedElements = []; var deletedElements = [];
var collectionString = key; var collectionString = key;
_.forEach(list, function(data) { _.forEach(list, function(data) {
// uncomment this line for debugging to log all autoupdates: // Uncomment this line for debugging to log all autoupdates:
// console.log("Received object: " + data.collection + ", " + data.id); // console.log("Received object: " + data.collection + ", " + data.id);
// remove (=eject) object from local DS store // remove (=eject) object from local DS store
@ -299,7 +334,6 @@ angular.module('OpenSlidesApp.core', [
]) ])
// Template hooks // Template hooks
.factory('templateHooks', [ .factory('templateHooks', [
function () { function () {
var hooks = {}; var hooks = {};

View File

@ -8,6 +8,13 @@ angular.module('OpenSlidesApp.core.projector', ['OpenSlidesApp.core'])
// Can be used to find out if the projector or the side is used // Can be used to find out if the projector or the side is used
.constant('REALM', 'projector') .constant('REALM', 'projector')
.run([
'autoupdate',
function (autoupdate) {
autoupdate.newConnect();
}
])
// Provider to register slides in a .config() statement. // Provider to register slides in a .config() statement.
.provider('slides', [ .provider('slides', [
function() { function() {
@ -84,10 +91,8 @@ angular.module('OpenSlidesApp.core.projector', ['OpenSlidesApp.core'])
'$scope', '$scope',
'$location', '$location',
'gettext', 'gettext',
'loadGlobalData',
'Projector', 'Projector',
function($scope, $location, gettext, loadGlobalData, Projector) { function($scope, $location, gettext, Projector) {
loadGlobalData();
$scope.error = ''; $scope.error = '';
// watch for changes in Projector // watch for changes in Projector

View File

@ -5,6 +5,7 @@
// The core module for the OpenSlides site // The core module for the OpenSlides site
angular.module('OpenSlidesApp.core.site', [ angular.module('OpenSlidesApp.core.site', [
'OpenSlidesApp.core', 'OpenSlidesApp.core',
'OpenSlidesApp.core.start',
'OpenSlidesApp.poll.majority', 'OpenSlidesApp.poll.majority',
'ui.router', 'ui.router',
'angular-loading-bar', 'angular-loading-bar',
@ -77,10 +78,7 @@ angular.module('OpenSlidesApp.core.site', [
this.$get = ['operator', function(operator) { this.$get = ['operator', function(operator) {
return { return {
registerScope: function (scope) { registerScope: function (scope) {
var that = this;
this.scope = scope; this.scope = scope;
this.updateMainMenu();
// TODO: operator.onOperatorChange(function () {that.updateMainMenu();});
}, },
updateMainMenu: function () { updateMainMenu: function () {
this.scope.elements = this.getElements(); this.scope.elements = this.getElements();
@ -660,28 +658,6 @@ angular.module('OpenSlidesApp.core.site', [
} }
]) ])
.directive('routeLoadingIndicator', [
'$rootScope',
'$state',
'gettext',
function($rootScope, $state, gettext) {
gettext('Loading ...');
return {
restrict: 'E',
template: "<div class='header spacer-bottom' ng-if='isRouteLoading'><div class='title'><h1><translate>Loading ...</translate> <i class='fa fa-spinner fa-pulse'></i></h1></div></div>",
link: function(scope, elem, attrs) {
scope.isRouteLoading = false;
$rootScope.$on('$stateChangeStart', function() {
scope.isRouteLoading = true;
});
$rootScope.$on('$stateChangeSuccess', function() {
scope.isRouteLoading = false;
});
}
};
}
])
/* This directive provides a csv import template. /* This directive provides a csv import template.
* Papa Parse is used to parse the csv file. Accepted attributes: * Papa Parse is used to parse the csv file. Accepted attributes:
* * change: * * change:

View File

@ -10,8 +10,10 @@ angular.module('OpenSlidesApp.core.start', [])
'$state', '$state',
'autoupdate', 'autoupdate',
'operator', 'operator',
function($http, $rootScope, $state, autoupdate, operator) { 'Group',
// Put the operator into the root scope 'mainMenu',
function($http, $rootScope, $state, autoupdate, operator, Group, mainMenu) {
$rootScope.startupWaitingEnabled = true;
$http.get('/users/whoami/').success(function(data) { $http.get('/users/whoami/').success(function(data) {
$rootScope.guest_enabled = data.guest_enabled; $rootScope.guest_enabled = data.guest_enabled;
if (data.user_id === null && !data.guest_enabled) { if (data.user_id === null && !data.guest_enabled) {
@ -19,46 +21,15 @@ angular.module('OpenSlidesApp.core.start', [])
$state.go('login', {guest_enabled: data.guest_enabled}); $state.go('login', {guest_enabled: data.guest_enabled});
} else { } else {
autoupdate.newConnect(); autoupdate.newConnect();
// TODO: Connect websocket autoupdate.firstMessageDeferred.promise.then(function () {
// Then operator.setUser(data.user_id, data.user); $rootScope.operator = operator; operator.setUser(data.user_id, data.user);
$rootScope.operator = operator;
mainMenu.updateMainMenu();
$rootScope.startupWaitingEnabled = false;
});
} }
}); });
} }
]) ]);
.factory('operator', [
'Group',
'User',
function (User, Group) {
var operator = {
user: null,
perms: [],
isAuthenticated: function () {
return !!this.user;
},
setUser: function(user_id, user_data) {
if (user_id && user_data) {
operator.user = User.inject(user_data);
operator.perms = operator.user.getPerms();
} else {
operator.user = null;
operator.perms = Group.get(1).permissions;
}
},
// Returns true if the operator has at least one perm of the perms-list.
hasPerms: function(perms) {
if (typeof perms === 'string') {
perms = perms.split(' ');
}
return _.intersection(perms, operator.perms).length > 0;
},
// Returns true if the operator is a member of group.
isInGroup: function(group) {
return _.indexOf(operator.user.groups_id, group.id) > -1;
},
};
return operator;
}
])
}()); }());

View File

@ -20,9 +20,15 @@
<div id="wrapper" ng-cloak> <div id="wrapper" ng-cloak>
<!-- please wait -->
<div id="startup-overlay" ng-if="startupWaitingEnabled">
<div>
<h1><i class="fa fa-spinner fa-pulse"></i></h1>
</div>
</div>
<!-- Header --> <!-- Header -->
<div id="header"> <div id="header">
<div ng-hide="connected" class="unconnected"></div>
<div class="containerOS"> <div class="containerOS">
<!-- Logo --> <!-- Logo -->
<div class="title"> <div class="title">
@ -174,8 +180,7 @@
<div class="containerOS"> <div class="containerOS">
<div class="col1" ng-class="isProjectorSidebar ? 'min' : 'max'"> <div class="col1" ng-class="isProjectorSidebar ? 'min' : 'max'">
<!-- dynamic views --> <!-- dynamic views -->
<route-loading-indicator></route-loading-indicator> <div ui-view></div>
<div ui-view ng-if="!isRouteLoading"></div>
<!-- footer --> <!-- footer -->
<div id="footer"> <div id="footer">
&copy; Copyright by <a href="http://www.openslides.org" target="_blank">OpenSlides</a> | &copy; Copyright by <a href="http://www.openslides.org" target="_blank">OpenSlides</a> |

View File

@ -198,14 +198,14 @@ angular.module('OpenSlidesApp.motions', [
'jsDataModel', 'jsDataModel',
'gettext', 'gettext',
'gettextCatalog', 'gettextCatalog',
'operator',
'Config', 'Config',
'lineNumberingService', 'lineNumberingService',
'diffService', 'diffService',
'OpenSlidesSettings', 'OpenSlidesSettings',
'Projector', 'Projector',
'operator',
function(DS, $http, MotionPoll, MotionChangeRecommendation, MotionComment, jsDataModel, gettext, gettextCatalog, function(DS, $http, MotionPoll, MotionChangeRecommendation, MotionComment, jsDataModel, gettext, gettextCatalog,
operator, Config, lineNumberingService, diffService, OpenSlidesSettings, Projector) { Config, lineNumberingService, diffService, OpenSlidesSettings, Projector, operator) {
var name = 'motions/motion'; var name = 'motions/motion';
return DS.defineResource({ return DS.defineResource({
name: name, name: name,

View File

@ -285,14 +285,6 @@ angular.module('OpenSlidesApp.motions.site', [
} }
]) ])
// Load all MotionWorkflows at startup
.run([
'Workflow',
function (Workflow) {
Workflow.findAll();
}
])
.factory('ChangeRecommendationForm', [ .factory('ChangeRecommendationForm', [
'gettextCatalog', 'gettextCatalog',
'Editor', 'Editor',

View File

@ -30,4 +30,9 @@ class UsersAppConfig(AppConfig):
# Register viewsets. # Register viewsets.
router.register(self.get_model('User').get_collection_string(), UserViewSet) router.register(self.get_model('User').get_collection_string(), UserViewSet)
router.register('users/group', GroupViewSet) router.register(self.get_model('Group').get_collection_string(), GroupViewSet)
def get_startup_elements(self):
from ..utils.collection import Collection
for model in ('User', 'Group'):
yield Collection(self.get_model(model).get_collection_string())

View File

@ -40,31 +40,13 @@ angular.module('OpenSlidesApp.users.site', [
abstract: true, abstract: true,
template: "<ui-view/>", template: "<ui-view/>",
}) })
.state('users.user.list', { .state('users.user.list', {})
resolve: { .state('users.user.create', {})
users: function(User) {
return User.findAll();
},
groups: function(Group) {
return Group.findAll();
}
}
})
.state('users.user.create', {
resolve: {
groups: function(Group) {
return Group.findAll();
}
}
})
.state('users.user.detail', { .state('users.user.detail', {
resolve: { resolve: {
user: function(User, $stateParams) { userId: ['$stateParams', function($stateParams) {
return User.find($stateParams.id); return $stateParams.id;
}, }]
groups: function(Group) {
return Group.findAll();
}
} }
}) })
// Redirects to user detail view and opens user edit form dialog, uses edit url. // Redirects to user detail view and opens user edit form dialog, uses edit url.
@ -72,8 +54,8 @@ angular.module('OpenSlidesApp.users.site', [
// (from users list controller use UserForm factory instead to open dialog in front of // (from users list controller use UserForm factory instead to open dialog in front of
// current view without redirect) // current view without redirect)
.state('users.user.detail.update', { .state('users.user.detail.update', {
onEnter: ['$stateParams', '$state', 'ngDialog', 'User', onEnter: ['$stateParams', '$state', 'ngDialog',
function($stateParams, $state, ngDialog, User) { function($stateParams, $state, ngDialog) {
ngDialog.open({ ngDialog.open({
template: 'static/templates/users/user-form.html', template: 'static/templates/users/user-form.html',
controller: 'UserUpdateCtrl', controller: 'UserUpdateCtrl',
@ -81,7 +63,7 @@ angular.module('OpenSlidesApp.users.site', [
closeByEscape: false, closeByEscape: false,
closeByDocument: false, closeByDocument: false,
resolve: { resolve: {
user: function() {return User.find($stateParams.id);} userId: function() {return $stateParams.id;}
} }
}); });
} }
@ -106,22 +88,14 @@ angular.module('OpenSlidesApp.users.site', [
controller: 'UserChangePasswordCtrl', controller: 'UserChangePasswordCtrl',
templateUrl: 'static/templates/users/user-change-password.html', templateUrl: 'static/templates/users/user-change-password.html',
resolve: { resolve: {
user: function(User, $stateParams) { userId: ['$stateParams', function($stateParams) {
return User.find($stateParams.id); return $stateParams.id;
} }]
} }
}) })
.state('users.user.import', { .state('users.user.import', {
url: '/import', url: '/import',
controller: 'UserImportCtrl', controller: 'UserImportCtrl',
resolve: {
groups: function(Group) {
return Group.findAll();
},
users: function(User) {
return User.findAll();
}
}
}) })
// groups // groups
.state('users.group', { .state('users.group', {
@ -134,9 +108,6 @@ angular.module('OpenSlidesApp.users.site', [
}) })
.state('users.group.list', { .state('users.group.list', {
resolve: { resolve: {
groups: function(Group) {
return Group.findAll();
},
permissions: function(Group) { permissions: function(Group) {
return Group.getPermissions(); return Group.getPermissions();
} }
@ -188,7 +159,7 @@ angular.module('OpenSlidesApp.users.site', [
} }
$scope.$watch( $scope.$watch(
function (scope) { function (scope) {
return scope.operator.hasPerms(perms); return scope.operator && scope.operator.hasPerms(perms);
}, },
function (value) { function (value) {
if ($attr.osPerms[0] === '!') { if ($attr.osPerms[0] === '!') {
@ -262,19 +233,15 @@ angular.module('OpenSlidesApp.users.site', [
return { return {
// ngDialog for user form // ngDialog for user form
getDialog: function (user) { getDialog: function (user) {
var resolve;
if (user) {
resolve = {
user: function(User) {return User.find(user.id);}
};
}
return { return {
template: 'static/templates/users/user-form.html', template: 'static/templates/users/user-form.html',
controller: (user) ? 'UserUpdateCtrl' : 'UserCreateCtrl', controller: (user) ? 'UserUpdateCtrl' : 'UserCreateCtrl',
className: 'ngdialog-theme-default wide-form', className: 'ngdialog-theme-default wide-form',
closeByEscape: false, closeByEscape: false,
closeByDocument: false, closeByDocument: false,
resolve: (resolve) ? resolve : null resolve: {
userId: function () {return user ? user.id : void 0;},
}
}; };
}, },
// angular-formly fields for user form // angular-formly fields for user form
@ -675,12 +642,12 @@ angular.module('OpenSlidesApp.users.site', [
'ngDialog', 'ngDialog',
'UserForm', 'UserForm',
'User', 'User',
'user', 'userId',
'Group', 'Group',
'Projector', 'Projector',
'ProjectionDefault', 'ProjectionDefault',
function($scope, ngDialog, UserForm, User, user, Group, Projector, ProjectionDefault) { function($scope, ngDialog, UserForm, User, userId, Group, Projector, ProjectionDefault) {
User.bindOne(user.id, $scope, 'user'); User.bindOne(userId, $scope, 'user');
Group.bindAll({where: {id: {'>': 1}}}, $scope, 'groups'); Group.bindAll({where: {id: {'>': 1}}}, $scope, 'groups');
$scope.$watch(function () { $scope.$watch(function () {
return Projector.lastModified(); return Projector.lastModified();
@ -738,13 +705,13 @@ angular.module('OpenSlidesApp.users.site', [
'User', 'User',
'UserForm', 'UserForm',
'Group', 'Group',
'user', 'userId',
function($scope, $state, $http, User, UserForm, Group, user) { function($scope, $state, $http, User, UserForm, Group, userId) {
Group.bindAll({where: {id: {'>': 2}}}, $scope, 'groups'); Group.bindAll({where: {id: {'>': 2}}}, $scope, 'groups');
$scope.alert = {}; $scope.alert = {};
// set initial values for form model by create deep copy of user object // set initial values for form model by create deep copy of user object
// so list/detail view is not updated while editing // so list/detail view is not updated while editing
$scope.model = angular.copy(user); $scope.model = angular.copy(User.get(userId));
// get all form fields // get all form fields
$scope.formFields = UserForm.getFormFields(); $scope.formFields = UserForm.getFormFields();
@ -803,11 +770,11 @@ angular.module('OpenSlidesApp.users.site', [
'$state', '$state',
'$http', '$http',
'User', 'User',
'user', 'userId',
'gettextCatalog', 'gettextCatalog',
'PasswordGenerator', 'PasswordGenerator',
function($scope, $state, $http, User, user, gettextCatalog, PasswordGenerator) { function($scope, $state, $http, User, userId, gettextCatalog, PasswordGenerator) {
User.bindOne(user.id, $scope, 'user'); User.bindOne(userId, $scope, 'user');
$scope.alert={}; $scope.alert={};
$scope.generatePassword = function () { $scope.generatePassword = function () {
$scope.new_password = PasswordGenerator.generate(); $scope.new_password = PasswordGenerator.generate();
@ -1210,7 +1177,7 @@ angular.module('OpenSlidesApp.users.site', [
$scope.groups.forEach(function (group) { $scope.groups.forEach(function (group) {
if ((_.indexOf(group.permissions, 'users.can_see_name') > -1) && if ((_.indexOf(group.permissions, 'users.can_see_name') > -1) &&
(_.indexOf(group.permissions, 'users.can_manage') > -1)){ (_.indexOf(group.permissions, 'users.can_manage') > -1)){
if (operator.isInGroup(group)){ if (!operator.user || operator.isInGroup(group)){
groups_danger.push(group); groups_danger.push(group);
} }
} }
@ -1342,19 +1309,15 @@ angular.module('OpenSlidesApp.users.site', [
}; };
$scope.openDialog = function (group) { $scope.openDialog = function (group) {
var resolve;
if (group) {
resolve = {
group: function() {return Group.find(group.id);}
};
}
ngDialog.open({ ngDialog.open({
template: 'static/templates/users/group-edit.html', template: 'static/templates/users/group-edit.html',
controller: group ? 'GroupRenameCtrl' : 'GroupCreateCtrl', controller: group ? 'GroupRenameCtrl' : 'GroupCreateCtrl',
className: 'ngdialog-theme-default wide-form', className: 'ngdialog-theme-default wide-form',
closeByEscape: false, closeByEscape: false,
closeByDocument: false, closeByDocument: false,
resolve: (resolve) ? resolve : null resolve: {
group: function () {return group;},
}
}); });
}; };
} }
@ -1439,10 +1402,15 @@ angular.module('OpenSlidesApp.users.site', [
'$rootScope', '$rootScope',
'$scope', '$scope',
'$http', '$http',
'$state',
'$stateParams', '$stateParams',
'$q',
'operator', 'operator',
'gettext', 'gettext',
function ($rootScope, $scope, $http, $stateParams, operator, gettext) { 'autoupdate',
'mainMenu',
'DS',
function ($rootScope, $scope, $http, $state, $stateParams, $q, operator, gettext, autoupdate, mainMenu, DS) {
$scope.alerts = []; $scope.alerts = [];
// get login info-text from server // get login info-text from server
@ -1478,11 +1446,19 @@ angular.module('OpenSlidesApp.users.site', [
$http.post('/users/login/', data).then( $http.post('/users/login/', data).then(
function (response) { function (response) {
// Success: User logged in. // Success: User logged in.
operator.setUser(response.data.user_id); // Clear store and reset deferred first message, if guests was enabled before.
DS.clear();
autoupdate.firstMessageDeferred = $q.defer();
// The next lines are partly the same lines as in core/start.js
autoupdate.newConnect();
autoupdate.firstMessageDeferred.promise.then(function () {
operator.setUser(response.data.user_id, response.data.user);
$rootScope.operator = operator;
mainMenu.updateMainMenu();
$scope.closeThisDialog(); $scope.closeThisDialog();
setTimeout(function(){ $state.go('home');
window.location.replace('/'); $rootScope.startupWaitingEnabled = false;
}, 1000); });
}, },
function (response) { function (response) {
// Error: Username or password is not correct. // Error: Username or password is not correct.

View File

@ -5,6 +5,7 @@ from django.utils.encoding import force_text
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from ..core.config import config from ..core.config import config
from ..utils.collection import CollectionElement
from ..utils.rest_api import ( from ..utils.rest_api import (
ModelViewSet, ModelViewSet,
Response, Response,
@ -13,7 +14,6 @@ from ..utils.rest_api import (
detail_route, detail_route,
status, status,
) )
from ..utils.collection import CollectionElement
from ..utils.views import APIView from ..utils.views import APIView
from .access_permissions import GroupAccessPermissions, UserAccessPermissions from .access_permissions import GroupAccessPermissions, UserAccessPermissions
from .models import Group, User from .models import Group, User
@ -209,6 +209,8 @@ class UserLoginView(APIView):
else: else:
# self.request.method == 'POST' # self.request.method == 'POST'
context['user_id'] = self.user.pk context['user_id'] = self.user.pk
user_collection = CollectionElement.from_instance(self.user)
context['user'] = user_collection.as_dict_for_user(self.user)
return super().get_context_data(**context) return super().get_context_data(**context)
@ -238,7 +240,7 @@ class WhoAmIView(APIView):
Appends also the serialized user if available. Appends also the serialized user if available.
""" """
user_id = self.request.user.pk user_id = self.request.user.pk
if self.request.user.pk is not None: if user_id is not None:
user_collection = CollectionElement.from_instance(self.request.user) user_collection = CollectionElement.from_instance(self.request.user)
user_data = user_collection.as_dict_for_user(self.request.user) user_data = user_collection.as_dict_for_user(self.request.user)
else: else:

View File

@ -21,7 +21,7 @@ def ws_add_site(message):
The group with the name 'user-None' stands for all anonymous users. The group with the name 'user-None' stands for all anonymous users.
Send all "starup-data" through the connection. Send all "startup-data" through the connection.
""" """
Group('site').add(message.reply_channel) Group('site').add(message.reply_channel)
message.channel_session['user_id'] = message.user.id message.channel_session['user_id'] = message.user.id
@ -42,11 +42,11 @@ def ws_add_site(message):
for collection in get_startup_elements(): for collection in get_startup_elements():
output.extend(collection.as_autoupdate_for_user(message.user)) output.extend(collection.as_autoupdate_for_user(message.user))
# Send all data. If there is no data, then onyl accept the connection # Send all data. If there is no data, then only accept the connection
if output: if output:
message.reply_channel.send({'text': json.dumps(output)}) message.reply_channel.send({'text': json.dumps(output)})
else: else:
message.reply_channel.send({"accept": True}) message.reply_channel.send({'accept': True})
@channel_session_user @channel_session_user

View File

@ -14,7 +14,7 @@ class TestWhoAmIView(TestCase):
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
self.assertEqual( self.assertEqual(
json.loads(response.content.decode()), json.loads(response.content.decode()),
{'user_id': None, 'guest_enabled': False}) {'user_id': None, 'user': None, 'guest_enabled': False})
def test_get_authenticated_user(self): def test_get_authenticated_user(self):
self.client.login(username='admin', password='admin') self.client.login(username='admin', password='admin')
@ -22,9 +22,8 @@ class TestWhoAmIView(TestCase):
response = self.client.get(self.url) response = self.client.get(self.url)
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
self.assertEqual( self.assertEqual(json.loads(response.content.decode()).get('user_id'), 1)
json.loads(response.content.decode()), self.assertEqual(json.loads(response.content.decode()).get('guest_enabled'), False)
{'user_id': 1, 'guest_enabled': False})
def test_post(self): def test_post(self):
response = self.client.post(self.url) response = self.client.post(self.url)
@ -79,9 +78,7 @@ class TestUserLoginView(TestCase):
{'username': 'admin', 'password': 'admin'}) {'username': 'admin', 'password': 'admin'})
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
self.assertEqual( self.assertEqual(json.loads(response.content.decode()).get('user_id'), 1)
json.loads(response.content.decode()),
{'user_id': 1})
def test_post_incorrect_data(self): def test_post_incorrect_data(self):
response = self.client.post( response = self.client.post(