diff options
author | Anton Tananaev <anton.tananaev@gmail.com> | 2017-05-13 11:01:48 +1200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-05-13 11:01:48 +1200 |
commit | 713d6c55a007aa80850810f447308976516bfa63 (patch) | |
tree | 057e9147e724a56b6e2f3820fcf3d9ab67561fdf /src/org/traccar/database | |
parent | 51920cae6438f8888090f177761a82afff33067f (diff) | |
parent | 6c17f85d04b224ff2a09265918765c9f4fc8cf94 (diff) | |
download | traccar-server-713d6c55a007aa80850810f447308976516bfa63.tar.gz traccar-server-713d6c55a007aa80850810f447308976516bfa63.tar.bz2 traccar-server-713d6c55a007aa80850810f447308976516bfa63.zip |
Merge pull request #3156 from Abyss777/computed_attributes
Implement computed attributes
Diffstat (limited to 'src/org/traccar/database')
-rw-r--r-- | src/org/traccar/database/AttributesManager.java | 199 | ||||
-rw-r--r-- | src/org/traccar/database/DataManager.java | 84 | ||||
-rw-r--r-- | src/org/traccar/database/PermissionsManager.java | 12 |
3 files changed, 295 insertions, 0 deletions
diff --git a/src/org/traccar/database/AttributesManager.java b/src/org/traccar/database/AttributesManager.java new file mode 100644 index 000000000..362d6130f --- /dev/null +++ b/src/org/traccar/database/AttributesManager.java @@ -0,0 +1,199 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Andrey Kunitsyn (andrey@traccar.org) + * + * 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 java.sql.SQLException; +import java.util.Collection; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +import org.traccar.Context; +import org.traccar.helper.Log; +import org.traccar.model.AttributePermission; +import org.traccar.model.Attribute; +import org.traccar.model.Device; +import org.traccar.model.DeviceAttribute; +import org.traccar.model.GroupAttribute; + +public class AttributesManager { + + private final DataManager dataManager; + + private final Map<Long, Attribute> attributes = new ConcurrentHashMap<>(); + private final Map<Long, Set<Long>> deviceAttributes = new ConcurrentHashMap<>(); + private final Map<Long, Set<Long>> deviceAttributesWithGroups = new ConcurrentHashMap<>(); + private final Map<Long, Set<Long>> groupAttributes = new ConcurrentHashMap<>(); + private final Map<Long, Set<Long>> userAttributes = new ConcurrentHashMap<>(); + + public AttributesManager(DataManager dataManager) { + this.dataManager = dataManager; + refreshAttributes(); + } + + public Set<Long> getUserAttributes(long userId) { + if (!userAttributes.containsKey(userId)) { + userAttributes.put(userId, new HashSet<Long>()); + } + return userAttributes.get(userId); + } + + public Set<Long> getGroupAttributes(long groupId) { + if (!groupAttributes.containsKey(groupId)) { + groupAttributes.put(groupId, new HashSet<Long>()); + } + return groupAttributes.get(groupId); + } + + public Set<Long> getDeviceAttributes(long deviceId) { + return getDeviceAttributes(deviceAttributes, deviceId); + } + + public Set<Long> getAllDeviceAttributes(long deviceId) { + return getDeviceAttributes(deviceAttributesWithGroups, deviceId); + } + + private Set<Long> getDeviceAttributes(Map<Long, Set<Long>> deviceAttributes, long deviceId) { + if (!deviceAttributes.containsKey(deviceId)) { + deviceAttributes.put(deviceId, new HashSet<Long>()); + } + return deviceAttributes.get(deviceId); + } + + public final void refreshAttributes() { + if (dataManager != null) { + try { + attributes.clear(); + for (Attribute attribute : dataManager.getAttributes()) { + attributes.put(attribute.getId(), attribute); + } + } catch (SQLException error) { + Log.warning(error); + } + } + refreshUserAttributes(); + refresh(); + } + + public final void refreshUserAttributes() { + if (dataManager != null) { + try { + userAttributes.clear(); + for (AttributePermission attributePermission : dataManager.getAttributePermissions()) { + getUserAttributes(attributePermission.getUserId()).add(attributePermission.getAttributeId()); + } + } catch (SQLException error) { + Log.warning(error); + } + } + } + + public final void refresh() { + if (dataManager != null) { + try { + + Collection<GroupAttribute> databaseGroupAttributes = dataManager.getGroupAttributes(); + + groupAttributes.clear(); + for (GroupAttribute groupAttribute : databaseGroupAttributes) { + getGroupAttributes(groupAttribute.getGroupId()).add(groupAttribute.getAttributeId()); + } + + Collection<DeviceAttribute> databaseDeviceAttributes = dataManager.getDeviceAttributes(); + Collection<Device> allDevices = Context.getDeviceManager().getAllDevices(); + + deviceAttributes.clear(); + deviceAttributesWithGroups.clear(); + + for (DeviceAttribute deviceAttribute : databaseDeviceAttributes) { + getDeviceAttributes(deviceAttribute.getDeviceId()) + .add(deviceAttribute.getAttributeId()); + getAllDeviceAttributes(deviceAttribute.getDeviceId()) + .add(deviceAttribute.getAttributeId()); + } + + for (Device device : allDevices) { + long groupId = device.getGroupId(); + while (groupId != 0) { + getAllDeviceAttributes(device.getId()).addAll(getGroupAttributes(groupId)); + if (Context.getDeviceManager().getGroupById(groupId) != null) { + groupId = Context.getDeviceManager().getGroupById(groupId).getGroupId(); + } else { + groupId = 0; + } + } + } + + } catch (SQLException error) { + Log.warning(error); + } + } + } + + public void addAttribute(Attribute attribute) throws SQLException { + dataManager.addAttribute(attribute); + attributes.put(attribute.getId(), attribute); + } + + public void updateAttribute(Attribute attribute) throws SQLException { + dataManager.updateAttribute(attribute); + Attribute cachedAttribute = attributes.get(attribute.getId()); + cachedAttribute.setDescription(attribute.getDescription()); + cachedAttribute.setAttribute(attribute.getAttribute()); + cachedAttribute.setExpression(attribute.getExpression()); + cachedAttribute.setType(attribute.getType()); + } + + public void removeAttribute(long computedAttributeId) throws SQLException { + dataManager.removeAttribute(computedAttributeId); + attributes.remove(computedAttributeId); + refreshUserAttributes(); + refresh(); + } + + public boolean checkAttribute(long userId, long attributeId) { + return getUserAttributes(userId).contains(attributeId); + } + + public Attribute getAttribute(long id) { + return attributes.get(id); + } + + public final Collection<Attribute> getAttributes(Set<Long> attributeIds) { + Collection<Attribute> result = new LinkedList<>(); + for (long attributeId : attributeIds) { + result.add(getAttribute(attributeId)); + } + return result; + } + + public final Set<Long> getAllAttributes() { + return attributes.keySet(); + } + + public final Set<Long> getManagedAttributes(long userId) { + Set<Long> attributes = new HashSet<>(); + attributes.addAll(getUserAttributes(userId)); + for (long managedUserId : Context.getPermissionsManager().getUserPermissions(userId)) { + attributes.addAll(getUserAttributes(managedUserId)); + } + return attributes; + } + +} diff --git a/src/org/traccar/database/DataManager.java b/src/org/traccar/database/DataManager.java index 2f2cf1275..840a8931c 100644 --- a/src/org/traccar/database/DataManager.java +++ b/src/org/traccar/database/DataManager.java @@ -37,13 +37,17 @@ import liquibase.resource.ResourceAccessor; import org.traccar.Config; import org.traccar.helper.Log; import org.traccar.model.AttributeAlias; +import org.traccar.model.AttributePermission; import org.traccar.model.Calendar; import org.traccar.model.CalendarPermission; +import org.traccar.model.Attribute; import org.traccar.model.Device; +import org.traccar.model.DeviceAttribute; import org.traccar.model.DevicePermission; import org.traccar.model.Event; import org.traccar.model.Geofence; import org.traccar.model.Group; +import org.traccar.model.GroupAttribute; import org.traccar.model.GroupGeofence; import org.traccar.model.GroupPermission; import org.traccar.model.Notification; @@ -552,4 +556,84 @@ public class DataManager { .executeUpdate(); } + public Collection<Attribute> getAttributes() throws SQLException { + return QueryBuilder.create(dataSource, getQuery("database.selectAttributes")) + .executeQuery(Attribute.class); + } + + public void addAttribute(Attribute attribute) throws SQLException { + attribute.setId(QueryBuilder.create(dataSource, getQuery("database.insertAttribute"), true) + .setObject(attribute) + .executeUpdate()); + } + + public void updateAttribute(Attribute attribute) throws SQLException { + QueryBuilder.create(dataSource, getQuery("database.updateAttribute")) + .setObject(attribute) + .executeUpdate(); + } + + public void removeAttribute(long computedAttributeId) throws SQLException { + QueryBuilder.create(dataSource, getQuery("database.deleteAttribute")) + .setLong("id", computedAttributeId) + .executeUpdate(); + } + + public Collection<AttributePermission> getAttributePermissions() throws SQLException { + return QueryBuilder.create(dataSource, getQuery("database.selectAttributePermissions")) + .executeQuery(AttributePermission.class); + } + + public void linkAttribute(long userId, long attributeId) throws SQLException { + QueryBuilder.create(dataSource, getQuery("database.linkAttribute")) + .setLong("userId", userId) + .setLong("attributeId", attributeId) + .executeUpdate(); + } + + public void unlinkAttribute(long userId, long attributeId) throws SQLException { + QueryBuilder.create(dataSource, getQuery("database.unlinkAttribute")) + .setLong("userId", userId) + .setLong("attributeId", attributeId) + .executeUpdate(); + } + + public Collection<GroupAttribute> getGroupAttributes() throws SQLException { + return QueryBuilder.create(dataSource, getQuery("database.selectGroupAttributes")) + .executeQuery(GroupAttribute.class); + } + + public void linkGroupAttribute(long groupId, long attributeId) throws SQLException { + QueryBuilder.create(dataSource, getQuery("database.linkGroupAttribute")) + .setLong("groupId", groupId) + .setLong("attributeId", attributeId) + .executeUpdate(); + } + + public void unlinkGroupAttribute(long groupId, long attributeId) throws SQLException { + QueryBuilder.create(dataSource, getQuery("database.unlinkGroupAttribute")) + .setLong("groupId", groupId) + .setLong("attributeId", attributeId) + .executeUpdate(); + } + + public Collection<DeviceAttribute> getDeviceAttributes() throws SQLException { + return QueryBuilder.create(dataSource, getQuery("database.selectDeviceAttributes")) + .executeQuery(DeviceAttribute.class); + } + + public void linkDeviceAttribute(long deviceId, long attributeId) throws SQLException { + QueryBuilder.create(dataSource, getQuery("database.linkDeviceAttribute")) + .setLong("deviceId", deviceId) + .setLong("attributeId", attributeId) + .executeUpdate(); + } + + public void unlinkDeviceAttribute(long deviceId, long attributeId) throws SQLException { + QueryBuilder.create(dataSource, getQuery("database.unlinkDeviceAttribute")) + .setLong("deviceId", deviceId) + .setLong("attributeId", attributeId) + .executeUpdate(); + } + } diff --git a/src/org/traccar/database/PermissionsManager.java b/src/org/traccar/database/PermissionsManager.java index e4bd6f5db..11f147c7c 100644 --- a/src/org/traccar/database/PermissionsManager.java +++ b/src/org/traccar/database/PermissionsManager.java @@ -310,6 +310,18 @@ public class PermissionsManager { } } + public void checkAttribute(long userId, long attributeId) throws SecurityException { + if (!Context.getAttributesManager().checkAttribute(userId, attributeId) && !isAdmin(userId)) { + checkManager(userId); + for (long managedUserId : getUserPermissions(userId)) { + if (Context.getAttributesManager().checkAttribute(managedUserId, attributeId)) { + return; + } + } + throw new SecurityException("Attribute access denied"); + } + } + public void checkCalendar(long userId, long calendarId) throws SecurityException { if (!Context.getCalendarManager().checkCalendar(userId, calendarId) && !isAdmin(userId)) { checkManager(userId); |