aboutsummaryrefslogtreecommitdiff
path: root/src/org/traccar/database
diff options
context:
space:
mode:
authorAbyss777 <abyss@fox5.ru>2017-05-10 13:27:49 +0500
committerAbyss777 <abyss@fox5.ru>2017-05-12 17:55:01 +0500
commit6c17f85d04b224ff2a09265918765c9f4fc8cf94 (patch)
tree5bbebd7f66b5af547267751fdb4de21283489716 /src/org/traccar/database
parent4ce5dd893d3b95fc759fd1d0e0dbf09d0d559936 (diff)
downloadtraccar-server-6c17f85d04b224ff2a09265918765c9f4fc8cf94.tar.gz
traccar-server-6c17f85d04b224ff2a09265918765c9f4fc8cf94.tar.bz2
traccar-server-6c17f85d04b224ff2a09265918765c9f4fc8cf94.zip
Implement computed attributes
Diffstat (limited to 'src/org/traccar/database')
-rw-r--r--src/org/traccar/database/AttributesManager.java199
-rw-r--r--src/org/traccar/database/DataManager.java84
-rw-r--r--src/org/traccar/database/PermissionsManager.java12
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 0c5f458a2..acbaac17b 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;
@@ -548,4 +552,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);