aboutsummaryrefslogtreecommitdiff
path: root/src/org/traccar/database
diff options
context:
space:
mode:
Diffstat (limited to 'src/org/traccar/database')
-rw-r--r--src/org/traccar/database/ConnectionManager.java3
-rw-r--r--src/org/traccar/database/DataManager.java92
-rw-r--r--src/org/traccar/database/GeofenceManager.java191
-rw-r--r--src/org/traccar/database/PermissionsManager.java7
4 files changed, 292 insertions, 1 deletions
diff --git a/src/org/traccar/database/ConnectionManager.java b/src/org/traccar/database/ConnectionManager.java
index ec5903548..6e47dfad3 100644
--- a/src/org/traccar/database/ConnectionManager.java
+++ b/src/org/traccar/database/ConnectionManager.java
@@ -155,7 +155,8 @@ public class ConnectionManager {
Log.warning(error);
}
for (long userId : Context.getPermissionsManager().getDeviceUsers(deviceId)) {
- if (listeners.containsKey(userId)) {
+ if (listeners.containsKey(userId) && (event.getGeofenceId() == 0
+ || Context.getGeofenceManager().checkGeofence(userId, event.getGeofenceId()))) {
for (UpdateListener listener : listeners.get(userId)) {
listener.onUpdateEvent(event, position);
}
diff --git a/src/org/traccar/database/DataManager.java b/src/org/traccar/database/DataManager.java
index 67b7d1e55..86c930c0b 100644
--- a/src/org/traccar/database/DataManager.java
+++ b/src/org/traccar/database/DataManager.java
@@ -48,11 +48,15 @@ import org.traccar.helper.Log;
import org.traccar.model.Device;
import org.traccar.model.DevicePermission;
import org.traccar.model.Event;
+import org.traccar.model.Geofence;
import org.traccar.model.Group;
+import org.traccar.model.GroupGeofence;
import org.traccar.model.GroupPermission;
import org.traccar.model.Position;
import org.traccar.model.Server;
import org.traccar.model.User;
+import org.traccar.model.UserDeviceGeofence;
+import org.traccar.model.GeofencePermission;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
@@ -368,6 +372,7 @@ public class DataManager implements IdentityManager {
Device cachedDevice = getDeviceById(device.getId());
cachedDevice.setStatus(device.getStatus());
cachedDevice.setMotion(device.getMotion());
+ cachedDevice.setGeofenceId(device.getGeofenceId());
}
public void removeDevice(long deviceId) throws SQLException {
@@ -524,4 +529,91 @@ public class DataManager implements IdentityManager {
return getEvents(deviceId, type, new Date(), to);
}
+ public Collection<Geofence> getGeofences() throws SQLException {
+ return QueryBuilder.create(dataSource, getQuery("database.selectGeofencesAll"))
+ .executeQuery(Geofence.class);
+ }
+
+ public Geofence getGeofence(long geofenceId) throws SQLException {
+ return QueryBuilder.create(dataSource, getQuery("database.selectGeofences"))
+ .setLong("id", geofenceId)
+ .executeQuerySingle(Geofence.class);
+ }
+
+ public void addGeofence(Geofence geofence) throws SQLException {
+ geofence.setId(QueryBuilder.create(dataSource, getQuery("database.insertGeofence"), true)
+ .setObject(geofence)
+ .executeUpdate());
+ }
+
+ public void updateGeofence(Geofence geofence) throws SQLException {
+ QueryBuilder.create(dataSource, getQuery("database.updateGeofence"))
+ .setObject(geofence)
+ .executeUpdate();
+ }
+
+ public void removeGeofence(long geofenceId) throws SQLException {
+ QueryBuilder.create(dataSource, getQuery("database.deleteGeofence"))
+ .setLong("id", geofenceId)
+ .executeUpdate();
+ }
+
+ public Collection<GeofencePermission> getGeofencePermissions() throws SQLException {
+ return QueryBuilder.create(dataSource, getQuery("database.selectGeofencePermissions"))
+ .executeQuery(GeofencePermission.class);
+ }
+
+ public void linkGeofence(long userId, long geofenceId) throws SQLException {
+ QueryBuilder.create(dataSource, getQuery("database.linkGeofence"))
+ .setLong("userId", userId)
+ .setLong("geofenceId", geofenceId)
+ .executeUpdate();
+ }
+
+ public void unlinkGeofence(long userId, long geofenceId) throws SQLException {
+ QueryBuilder.create(dataSource, getQuery("database.unlinkGeofence"))
+ .setLong("userId", userId)
+ .setLong("geofenceId", geofenceId)
+ .executeUpdate();
+ }
+
+ public Collection<GroupGeofence> getGroupGeofences() throws SQLException {
+ return QueryBuilder.create(dataSource, getQuery("database.selectGroupGeofences"))
+ .executeQuery(GroupGeofence.class);
+ }
+
+ public void linkGroupGeofence(long groupId, long geofenceId) throws SQLException {
+ QueryBuilder.create(dataSource, getQuery("database.linkGroupGeofence"))
+ .setLong("groupId", groupId)
+ .setLong("geofenceId", geofenceId)
+ .executeUpdate();
+ }
+
+ public void unlinkGroupGeofence(long groupId, long geofenceId) throws SQLException {
+ QueryBuilder.create(dataSource, getQuery("database.unlinkGroupGeofence"))
+ .setLong("groupId", groupId)
+ .setLong("geofenceId", geofenceId)
+ .executeUpdate();
+ }
+
+ public Collection<UserDeviceGeofence> getUserDeviceGeofences() throws SQLException {
+ return QueryBuilder.create(dataSource, getQuery("database.selectUserDeviceGeofences"))
+ .executeQuery(UserDeviceGeofence.class);
+ }
+
+ public void linkUserDeviceGeofence(long userId, long deviceId, long geofenceId) throws SQLException {
+ QueryBuilder.create(dataSource, getQuery("database.linkUserDeviceGeofence"))
+ .setLong("userId", userId)
+ .setLong("deviceId", deviceId)
+ .setLong("geofenceId", geofenceId)
+ .executeUpdate();
+ }
+
+ public void unlinkUserDeviceGeofence(long userId, long deviceId, long geofenceId) throws SQLException {
+ QueryBuilder.create(dataSource, getQuery("database.unlinkUserDeviceGeofence"))
+ .setLong("userId", userId)
+ .setLong("deviceId", deviceId)
+ .setLong("geofenceId", geofenceId)
+ .executeUpdate();
+ }
}
diff --git a/src/org/traccar/database/GeofenceManager.java b/src/org/traccar/database/GeofenceManager.java
new file mode 100644
index 000000000..64afc876c
--- /dev/null
+++ b/src/org/traccar/database/GeofenceManager.java
@@ -0,0 +1,191 @@
+package org.traccar.database;
+
+import java.sql.SQLException;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+import org.traccar.helper.Log;
+import org.traccar.model.Device;
+import org.traccar.model.Geofence;
+import org.traccar.model.GroupGeofence;
+import org.traccar.model.UserDeviceGeofence;
+import org.traccar.model.GeofencePermission;
+
+public class GeofenceManager {
+
+ private final DataManager dataManager;
+
+ private final Map<Long, Geofence> geofences = new HashMap<>();
+ private final Map<Long, Set<Long>> userGeofences = new HashMap<>();
+ private final Map<Long, Set<Long>> groupGeofences = new HashMap<>();
+
+ private final Map<Long, Set<Long>> deviceGeofences = new HashMap<>();
+ private final Map<Long, Map<Long, Set<Long>>> userDeviceGeofences = new HashMap<>();
+
+ private final ReadWriteLock deviceGeofencesLock = new ReentrantReadWriteLock();
+ private final ReadWriteLock geofencesLock = new ReentrantReadWriteLock();
+ private final ReadWriteLock groupGeofencesLock = new ReentrantReadWriteLock();
+
+ public GeofenceManager(DataManager dataManager) {
+ this.dataManager = dataManager;
+ refresh();
+ }
+
+ public Set<Long> getUserGeofencesIds(long userId) {
+ if (!userGeofences.containsKey(userId)) {
+ userGeofences.put(userId, new HashSet<Long>());
+ }
+ return userGeofences.get(userId);
+ }
+
+ private Set<Long> getGroupGeofences(long groupId) {
+ if (!groupGeofences.containsKey(groupId)) {
+ groupGeofences.put(groupId, new HashSet<Long>());
+ }
+ return groupGeofences.get(groupId);
+ }
+
+ public Set<Long> getAllDeviceGeofences(long deviceId) {
+ deviceGeofencesLock.readLock().lock();
+ try {
+ return getDeviceGeofences(deviceGeofences, deviceId);
+ } finally {
+ deviceGeofencesLock.readLock().unlock();
+ }
+
+ }
+
+ public Set<Long> getUserDeviceGeofences(long userId, long deviceId) {
+ deviceGeofencesLock.readLock().lock();
+ try {
+ return getUserDeviceGeofencesUnlocked(userId, deviceId);
+ } finally {
+ deviceGeofencesLock.readLock().unlock();
+ }
+ }
+
+ private Set<Long> getDeviceGeofences(Map<Long, Set<Long>> deviceGeofences, long deviceId) {
+ if (!deviceGeofences.containsKey(deviceId)) {
+ deviceGeofences.put(deviceId, new HashSet<Long>());
+ }
+ return deviceGeofences.get(deviceId);
+ }
+
+ private Set<Long> getUserDeviceGeofencesUnlocked(long userId, long deviceId) {
+ if (!userDeviceGeofences.containsKey(userId)) {
+ userDeviceGeofences.put(userId, new HashMap<Long, Set<Long>>());
+ }
+ return getDeviceGeofences(userDeviceGeofences.get(userId), deviceId);
+ }
+
+ public final void refresh() {
+ if (dataManager != null) {
+ try {
+ geofencesLock.writeLock().lock();
+ groupGeofencesLock.writeLock().lock();
+ deviceGeofencesLock.writeLock().lock();
+ try {
+ geofences.clear();
+ for (Geofence geofence : dataManager.getGeofences()) {
+ geofences.put(geofence.getId(), geofence);
+ }
+
+ userGeofences.clear();
+ for (GeofencePermission geofencePermission : dataManager.getGeofencePermissions()) {
+ getUserGeofencesIds(geofencePermission.getUserId()).add(geofencePermission.getGeofenceId());
+ }
+
+ groupGeofences.clear();
+ for (GroupGeofence groupGeofence : dataManager.getGroupGeofences()) {
+ getGroupGeofences(groupGeofence.getGroupId()).add(groupGeofence.getGeofenceId());
+ }
+
+ deviceGeofences.clear();
+
+ for (Map.Entry<Long, Map<Long, Set<Long>>> deviceGeofence : userDeviceGeofences.entrySet()) {
+ deviceGeofence.getValue().clear();
+ }
+ userDeviceGeofences.clear();
+
+ for (UserDeviceGeofence userDeviceGeofence : dataManager.getUserDeviceGeofences()) {
+ getDeviceGeofences(deviceGeofences, userDeviceGeofence.getDeviceId())
+ .add(userDeviceGeofence.getGeofenceId());
+ getUserDeviceGeofencesUnlocked(userDeviceGeofence.getUserId(), userDeviceGeofence.getDeviceId())
+ .add(userDeviceGeofence.getGeofenceId());
+ }
+ for (Device device : dataManager.getAllDevices()) {
+ long groupId = device.getGroupId();
+ while (groupId != 0) {
+ getDeviceGeofences(deviceGeofences, device.getId()).addAll(getGroupGeofences(groupId));
+ groupId = dataManager.getGroupById(groupId).getGroupId();
+ }
+ }
+
+ } finally {
+ geofencesLock.writeLock().unlock();
+ groupGeofencesLock.writeLock().unlock();
+ deviceGeofencesLock.writeLock().unlock();
+ }
+
+ } catch (SQLException error) {
+ Log.warning(error);
+ }
+ }
+ }
+
+ public final Collection<Geofence> getAllGeofences() {
+ geofencesLock.readLock().lock();
+ try {
+ return geofences.values();
+ } finally {
+ geofencesLock.readLock().unlock();
+ }
+ }
+
+ public final Collection<Geofence> getUserGeofences(long userId) {
+ geofencesLock.readLock().lock();
+ try {
+ Collection<Geofence> result = new LinkedList<>();
+ for (Long geofenceId : getUserGeofencesIds(userId)) {
+ result.add(getGeofence(geofenceId));
+ }
+ return result;
+ } finally {
+ geofencesLock.readLock().unlock();
+ }
+ }
+
+ public final Geofence getGeofence(Long geofenceId) {
+ geofencesLock.readLock().lock();
+ try {
+ return geofences.get(geofenceId);
+ } finally {
+ geofencesLock.readLock().unlock();
+ }
+ }
+
+ public final void updateGeofence(Geofence geofence) {
+ geofencesLock.writeLock().lock();
+ try {
+ geofences.put(geofence.getId(), geofence);
+ } finally {
+ geofencesLock.writeLock().unlock();
+ }
+ try {
+ dataManager.updateGeofence(geofence);
+ } catch (SQLException error) {
+ Log.warning(error);
+ }
+ }
+
+ public boolean checkGeofence(long userId, long geofenceId) {
+ return getUserGeofencesIds(userId).contains(geofenceId);
+ }
+
+}
diff --git a/src/org/traccar/database/PermissionsManager.java b/src/org/traccar/database/PermissionsManager.java
index 08d44b382..96a6488ef 100644
--- a/src/org/traccar/database/PermissionsManager.java
+++ b/src/org/traccar/database/PermissionsManager.java
@@ -15,6 +15,7 @@
*/
package org.traccar.database;
+import org.traccar.Context;
import org.traccar.helper.Log;
import org.traccar.model.Device;
import org.traccar.model.DevicePermission;
@@ -145,4 +146,10 @@ public class PermissionsManager {
}
}
+ public void checkGeofence(long userId, long geofenceId) throws SecurityException {
+ if (!Context.getGeofenceManager().checkGeofence(userId, geofenceId) && !isAdmin(userId)) {
+ throw new SecurityException("Geofence access denied");
+ }
+ }
+
}