Skip to content

Commit

Permalink
For #214 #215 - added possibility to find out allowed maximum number …
Browse files Browse the repository at this point in the history
…of devices setting for a user, added tests and corresponding UI message
  • Loading branch information
vitalidze committed Sep 30, 2015
1 parent c5a663a commit 1febd39
Show file tree
Hide file tree
Showing 10 changed files with 136 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,7 @@
import org.traccar.web.client.model.NotificationServiceAsync;
import org.traccar.web.client.model.UserProperties;
import org.traccar.web.client.view.*;
import org.traccar.web.shared.model.ApplicationSettings;
import org.traccar.web.shared.model.NotificationSettings;
import org.traccar.web.shared.model.NotificationTemplate;
import org.traccar.web.shared.model.User;
import org.traccar.web.shared.model.*;

import com.google.gwt.core.client.GWT;
import com.sencha.gxt.data.shared.ListStore;
Expand Down Expand Up @@ -87,23 +84,36 @@ public void onSuccess(List<User> result) {

@Override
public void onAdd() {
new UserDialog(
new User(),
new UserDialog.UserHandler() {
class AddHandler implements UserDialog.UserHandler {
@Override
public void onSave(final User user) {
Application.getDataService().addUser(user, new BaseAsyncCallback<User>(i18n) {
@Override
public void onSave(User user) {
Application.getDataService().addUser(user, new BaseAsyncCallback<User>(i18n) {
@Override
public void onSuccess(User result) {
userStore.add(result);
}
public void onSuccess(User result) {
userStore.add(result);
}
@Override
public void onFailure(Throwable caught) {
AlertMessageBox msg;
if (caught instanceof InvalidMaxDeviceNumberForUserException) {
InvalidMaxDeviceNumberForUserException e = (InvalidMaxDeviceNumberForUserException) caught;
msg = new AlertMessageBox(i18n.error(), i18n.errMaxNumOfDevicesExceeded(e.getAllowedDevicesNumber()));
} else {
msg = new AlertMessageBox(i18n.error(), i18n.errUsernameTaken());
}
msg.addDialogHideHandler(new DialogHideEvent.DialogHideHandler() {
@Override
public void onFailure(Throwable caught) {
new AlertMessageBox(i18n.error(), i18n.errUsernameTaken()).show();
public void onDialogHide(DialogHideEvent event) {
new UserDialog(user, AddHandler.this).show();
}
});
msg.show();
}
}).show();
});
}
}

new UserDialog(new User(), new AddHandler()).show();
}

@Override
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/org/traccar/web/client/i18n/Messages.java
Original file line number Diff line number Diff line change
Expand Up @@ -406,4 +406,6 @@ String defaultNotificationTemplate(@Select DeviceEventType type,
String traceInterval();

String errAccessDenied();

String errMaxNumOfDevicesExceeded(int maxNumOfDevices);
}
4 changes: 2 additions & 2 deletions src/main/java/org/traccar/web/client/model/DataService.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public interface DataService extends RemoteService {

List<User> getUsers();

User addUser(User user);
User addUser(User user) throws InvalidMaxDeviceNumberForUserException;

User updateUser(User user) throws AccessDeniedException;

Expand Down Expand Up @@ -69,7 +69,7 @@ public interface DataService extends RemoteService {

String getTrackerServerLog(short sizeKb);

void saveRoles(List<User> users);
void saveRoles(List<User> users) throws InvalidMaxDeviceNumberForUserException;

List<GeoFence> getGeoFences();

Expand Down
29 changes: 20 additions & 9 deletions src/main/java/org/traccar/web/server/model/DataServiceImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ public List<User> getUsers() {
@RequireUser(roles = { Role.ADMIN, Role.MANAGER })
@RequireWrite
@Override
public User addUser(User user) {
public User addUser(User user) throws InvalidMaxDeviceNumberForUserException {
User currentUser = getSessionUser();
if (user.getLogin() == null || user.getLogin().isEmpty() ||
user.getPassword() == null || user.getPassword().isEmpty()) {
Expand All @@ -227,6 +227,7 @@ public User addUser(User user) {
user.setAdmin(false);
}
user.setManagedBy(currentUser);
validateMaximumNumberOfDevices(user, null, user.getMaxNumOfDevices());
user.setPasswordHashMethod(getApplicationSettings().getDefaultHashImplementation());
user.setPassword(user.getPasswordHashMethod().doHash(user.getPassword(), getApplicationSettings().getSalt()));
if (user.getUserSettings() == null) {
Expand All @@ -241,6 +242,15 @@ public User addUser(User user) {
}
}

private void validateMaximumNumberOfDevices(User user, Integer originalValue, Integer newValue) throws InvalidMaxDeviceNumberForUserException {
if (user.getManagedBy() != null && newValue != null) {
int allowed = user.getManagedBy().getNumberOfDevicesToDistribute() + (originalValue == null ? 0 : originalValue);
if (allowed - newValue < 0) {
throw new InvalidMaxDeviceNumberForUserException(allowed);
}
}
}

@Transactional
@RequireUser
@RequireWrite
Expand All @@ -264,10 +274,8 @@ public User updateUser(User user) throws AccessDeniedException {
currentUser.setPasswordHashMethod(getApplicationSettings().getDefaultHashImplementation());
currentUser.setPassword(currentUser.getPasswordHashMethod().doHash(user.getPassword(), getApplicationSettings().getSalt()));
}
if(currentUser.getAdmin() || currentUser.getManager())
if (currentUser.getAdmin() || currentUser.getManager())
{
currentUser.setMaxNumOfDevices(user.getMaxNumOfDevices());
currentUser.setExpirationDate(user.getExpirationDate());
if (currentUser.getAdmin()) {
currentUser.setAdmin(user.getAdmin());
}
Expand Down Expand Up @@ -781,7 +789,7 @@ public String getTrackerServerLog(short sizeKB) {
@RequireUser(roles = { Role.ADMIN, Role.MANAGER })
@RequireWrite
@Override
public void saveRoles(List<User> users) {
public void saveRoles(List<User> users) throws InvalidMaxDeviceNumberForUserException {
if (users == null || users.isEmpty()) {
return;
}
Expand All @@ -794,11 +802,14 @@ public void saveRoles(List<User> users) {
user.setAdmin(_user.getAdmin());
}
user.setManager(_user.getManager());
user.setReadOnly(_user.getReadOnly());
user.setArchive(_user.isArchive());
user.setExpirationDate(_user.getExpirationDate());
user.setBlocked(_user.isBlocked());
user.setMaxNumOfDevices(_user.getMaxNumOfDevices());
if (user.getId() != currentUser.getId()) {
user.setReadOnly(_user.getReadOnly());
user.setBlocked(_user.isBlocked());
validateMaximumNumberOfDevices(user, user.getMaxNumOfDevices(), _user.getMaxNumOfDevices());
user.setMaxNumOfDevices(_user.getMaxNumOfDevices());
user.setExpirationDate(_user.getExpirationDate());
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright 2015 Vitaly Litvak (vitavaque@gmail.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.traccar.web.shared.model;

public class InvalidMaxDeviceNumberForUserException extends TraccarException {
private int allowedDevicesNumber;

public InvalidMaxDeviceNumberForUserException(int allowedDevicesNumber) {
this.allowedDevicesNumber = allowedDevicesNumber;
}

public InvalidMaxDeviceNumberForUserException() {
}

public int getAllowedDevicesNumber() {
return allowedDevicesNumber;
}
}
26 changes: 26 additions & 0 deletions src/main/java/org/traccar/web/shared/model/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,32 @@ public User getUserWhoReachedLimitOnDevicesNumber() {
return null;
}

public int getNumberOfDevicesToDistribute() {
Integer maxNumberOfDevices = getMaxNumOfDevices();
User manager = this;
while (maxNumberOfDevices == null && manager != null) {
maxNumberOfDevices = manager.getMaxNumOfDevices();
manager = manager.getManagedBy();
}
if (maxNumberOfDevices == null) {
return Integer.MAX_VALUE;
}
int alreadyDistributedNumberOfDevices = 0;
Set<User> users = manager.getManagedUsers();
while (!users.isEmpty()) {
Set<User> nextLevelUsers = new HashSet<User>();
for (User user : users) {
if (user.getMaxNumOfDevices() == null) {
nextLevelUsers.addAll(user.getManagedUsers());
} else {
alreadyDistributedNumberOfDevices += user.getMaxNumOfDevices();
}
}
users = nextLevelUsers;
}
return Math.max(0, maxNumberOfDevices - alreadyDistributedNumberOfDevices);
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ address = Address
# user dialog
administrator = Administrator
errUsernameTaken = Username is already taken
errMaxNumOfDevicesExceeded = Maximum number of devices should not exceed {0}
manager = Manager
event = Event
deviceEventType = Unknown event
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ address = Адрес
# user dialog
administrator = Администратор
errUsernameTaken = Такое имя пользователя уже занято
errMaxNumOfDevicesExceeded = Максимальное количество устройств не должно быть больше {0}
manager = Менеджер
event = Событие
deviceEventType = Неизвестное событие
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ public void testDeleteDeviceWithSpecificGeoFence() throws TraccarException {
}

@Test
public void testDeleteUserWithNotificationSettings() throws AccessDeniedException {
public void testDeleteUserWithNotificationSettings() throws TraccarException {
Long originalUserId = injector.getProvider(User.class).get().getId();

User user = new User("test", "test");
Expand All @@ -153,7 +153,7 @@ public void testDeleteUserWithNotificationSettings() throws AccessDeniedExceptio
}

@Test
public void testResetPasswordByAdmin() throws AccessDeniedException {
public void testResetPasswordByAdmin() throws TraccarException {
User user = new User("test", "test");
user = dataService.addUser(user);

Expand All @@ -166,7 +166,7 @@ public void testResetPasswordByAdmin() throws AccessDeniedException {
}

@Test
public void testResetPasswordByManager() throws AccessDeniedException {
public void testResetPasswordByManager() throws TraccarException {
User manager = new User("manager", "manager");
manager.setManager(Boolean.TRUE);
manager = dataService.addUser(manager);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.junit.Test;

import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;

public class UserDevicesRestrictionTest {
Expand Down Expand Up @@ -89,6 +90,19 @@ public void testStrictHierarchyAddDevicesToLowestLevels() {
testStrictHierarchy(0, 0, 0, 0, 0, 0, 0, 0, 0);
}

@Test
public void testStrictNumberOfDevicesToDistribute() {
assertEquals(20, m1.getNumberOfDevicesToDistribute());
assertEquals(20, m2.getNumberOfDevicesToDistribute());
assertEquals(40, m3.getNumberOfDevicesToDistribute());
assertEquals(40, m4.getNumberOfDevicesToDistribute());
assertEquals(10, u1.getNumberOfDevicesToDistribute());
assertEquals(20, u2.getNumberOfDevicesToDistribute());
assertEquals(40, u3.getNumberOfDevicesToDistribute());
assertEquals(10, u4.getNumberOfDevicesToDistribute());
assertEquals(40, u5.getNumberOfDevicesToDistribute());
}

private void testStrictHierarchy(int dm1,
int dm2,
int dm3,
Expand Down Expand Up @@ -149,6 +163,15 @@ public void createWeirdHierarchy() {
m5 = m("m5", 100, m6);
}

@Test
public void testWeirdHierarchyNumberOfDevicesToDistribute() {
assertEquals(50, m5.getNumberOfDevicesToDistribute());
assertEquals(0, m6.getNumberOfDevicesToDistribute());
assertEquals(0, m7.getNumberOfDevicesToDistribute());
assertEquals(90, m8.getNumberOfDevicesToDistribute());
assertEquals(90, m9.getNumberOfDevicesToDistribute());
}

@Test
public void testWeirdHierarchyInitial() {
testWeirdHierarchy(100, 50, 50, 50, 50, 50, 50, 50, 50);
Expand Down Expand Up @@ -198,6 +221,7 @@ private User m(String name, Integer maxNumOfDevices, User... managedUsers) {
private User u(String name, Integer maxNumOfDevices) {
User user = new User(name);
user.setMaxNumOfDevices(maxNumOfDevices);
user.setManagedUsers(Collections.<User>emptySet());
return user;
}

Expand Down

0 comments on commit 1febd39

Please sign in to comment.