/* * Copyright 2015 - 2016 Anton Tananaev (anton.tananaev@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.database; import org.traccar.Context; import org.traccar.helper.Log; import org.traccar.model.Device; import org.traccar.model.DevicePermission; import org.traccar.model.Group; import org.traccar.model.GroupPermission; import org.traccar.model.Server; import org.traccar.model.User; import java.sql.SQLException; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; public class PermissionsManager { private final DataManager dataManager; private volatile Server server; private final Map users = new HashMap<>(); private final Map> groupPermissions = new HashMap<>(); private final Map> devicePermissions = new HashMap<>(); private final Map> deviceUsers = new HashMap<>(); public Set getGroupPermissions(long userId) { if (!groupPermissions.containsKey(userId)) { groupPermissions.put(userId, new HashSet()); } return groupPermissions.get(userId); } public Set getDevicePermissions(long userId) { if (!devicePermissions.containsKey(userId)) { devicePermissions.put(userId, new HashSet()); } return devicePermissions.get(userId); } public Set getDeviceUsers(long deviceId) { if (!deviceUsers.containsKey(deviceId)) { deviceUsers.put(deviceId, new HashSet()); } return deviceUsers.get(deviceId); } public PermissionsManager(DataManager dataManager) { this.dataManager = dataManager; refresh(); } public final void refresh() { users.clear(); groupPermissions.clear(); devicePermissions.clear(); try { server = dataManager.getServer(); for (User user : dataManager.getUsers()) { users.put(user.getId(), user); } GroupTree groupTree = new GroupTree(Context.getDeviceManager().getAllGroups(), Context.getDeviceManager().getAllDevices()); for (GroupPermission permission : dataManager.getGroupPermissions()) { Set userGroupPermissions = getGroupPermissions(permission.getUserId()); Set userDevicePermissions = getDevicePermissions(permission.getUserId()); userGroupPermissions.add(permission.getGroupId()); for (Group group : groupTree.getGroups(permission.getGroupId())) { userGroupPermissions.add(group.getId()); } for (Device device : groupTree.getDevices(permission.getGroupId())) { userDevicePermissions.add(device.getId()); } } for (DevicePermission permission : dataManager.getDevicePermissions()) { getDevicePermissions(permission.getUserId()).add(permission.getDeviceId()); } } catch (SQLException error) { Log.warning(error); } for (Map.Entry> entry : devicePermissions.entrySet()) { for (long deviceId : entry.getValue()) { getDeviceUsers(deviceId).add(entry.getKey()); } } } public boolean isAdmin(long userId) { return users.containsKey(userId) && users.get(userId).getAdmin(); } public void checkAdmin(long userId) throws SecurityException { if (!isAdmin(userId)) { throw new SecurityException("Admin access required"); } } public void checkUser(long userId, long otherUserId) throws SecurityException { if (userId != otherUserId) { checkAdmin(userId); } } public void checkGroup(long userId, long groupId) throws SecurityException { if (!getGroupPermissions(userId).contains(groupId)) { throw new SecurityException("Group access denied"); } } public void checkDevice(long userId, long deviceId) throws SecurityException { if (!getDevicePermissions(userId).contains(deviceId)) { throw new SecurityException("Device access denied"); } } public void checkRegistration(long userId) { if (!server.getRegistration() && !isAdmin(userId)) { throw new SecurityException("Registration disabled"); } } public void checkReadonly(long userId) { if (server.getReadonly() && !isAdmin(userId)) { throw new SecurityException("Readonly user"); } } public void checkGeofence(long userId, long geofenceId) throws SecurityException { if (!Context.getGeofenceManager().checkGeofence(userId, geofenceId) && !isAdmin(userId)) { throw new SecurityException("Geofence access denied"); } } public Server getServer() { return server; } public void updateServer(Server server) throws SQLException { dataManager.updateServer(server); this.server = server; } }