Browse Source

Merge branch 'master' into kris/request_protector_app

pull/58/head
jonathan 4 years ago
parent
commit
3ba2407f61
12 changed files with 130 additions and 16 deletions
  1. +1
    -0
      bubble-server/src/main/java/bubble/ApiConstants.java
  2. +2
    -1
      bubble-server/src/main/java/bubble/dao/account/TrustedClientDAO.java
  3. +2
    -1
      bubble-server/src/main/java/bubble/dao/app/AppDataDAO.java
  4. +9
    -5
      bubble-server/src/main/java/bubble/dao/device/DeviceDAO.java
  5. +10
    -1
      bubble-server/src/main/java/bubble/dao/device/FlexRouterDAO.java
  6. +7
    -0
      bubble-server/src/main/java/bubble/dao/device/HasDeviceDAO.java
  7. +6
    -5
      bubble-server/src/main/java/bubble/resources/account/MeResource.java
  8. +60
    -0
      bubble-server/src/main/java/bubble/resources/device/DeviceTypesResource.java
  9. +3
    -2
      bubble-server/src/main/java/bubble/resources/device/DevicesResource.java
  10. +5
    -0
      bubble-server/src/main/java/bubble/service/device/DeviceService.java
  11. +24
    -0
      bubble-server/src/main/java/bubble/service/device/StandardDeviceService.java
  12. +1
    -1
      bubble-server/src/main/resources/META-INF/bubble/bubble.properties

+ 1
- 0
bubble-server/src/main/java/bubble/ApiConstants.java View File

@@ -216,6 +216,7 @@ public class ApiConstants {
public static final String EP_NODES = "/nodes"; public static final String EP_NODES = "/nodes";
public static final String EP_DEVICES = "/devices"; public static final String EP_DEVICES = "/devices";
public static final String EP_DEVICE_TYPES = "/deviceTypes"; public static final String EP_DEVICE_TYPES = "/deviceTypes";
public static final String EP_DEFAULT_SECURITY_LEVEL = "/defaultSecurityLevel";
public static final String EP_FLEX_ROUTERS = "/flexRouters"; public static final String EP_FLEX_ROUTERS = "/flexRouters";
public static final String EP_MODEL = "/model"; public static final String EP_MODEL = "/model";
public static final String EP_VPN = "/vpn"; public static final String EP_VPN = "/vpn";


+ 2
- 1
bubble-server/src/main/java/bubble/dao/account/TrustedClientDAO.java View File

@@ -4,6 +4,7 @@
*/ */
package bubble.dao.account; package bubble.dao.account;


import bubble.dao.device.HasDeviceDAO;
import bubble.model.account.TrustedClient; import bubble.model.account.TrustedClient;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.cobbzilla.wizard.model.Identifiable; import org.cobbzilla.wizard.model.Identifiable;
@@ -12,7 +13,7 @@ import org.springframework.stereotype.Repository;
import static java.util.UUID.randomUUID; import static java.util.UUID.randomUUID;


@Repository @Slf4j @Repository @Slf4j
public class TrustedClientDAO extends AccountOwnedEntityDAO<TrustedClient> {
public class TrustedClientDAO extends AccountOwnedEntityDAO<TrustedClient> implements HasDeviceDAO {


@Override protected String getNameField() { return Identifiable.UUID; } @Override protected String getNameField() { return Identifiable.UUID; }




+ 2
- 1
bubble-server/src/main/java/bubble/dao/app/AppDataDAO.java View File

@@ -4,6 +4,7 @@
*/ */
package bubble.dao.app; package bubble.dao.app;


import bubble.dao.device.HasDeviceDAO;
import bubble.model.account.Account; import bubble.model.account.Account;
import bubble.model.app.AppData; import bubble.model.app.AppData;
import bubble.model.app.BubbleApp; import bubble.model.app.BubbleApp;
@@ -26,7 +27,7 @@ import static org.hibernate.criterion.Restrictions.eq;


@SuppressWarnings("Duplicates") @SuppressWarnings("Duplicates")
@Repository @Slf4j @Repository @Slf4j
public class AppDataDAO extends AppTemplateEntityDAO<AppData> {
public class AppDataDAO extends AppTemplateEntityDAO<AppData> implements HasDeviceDAO {


public static final Order KEY_ASC = Order.asc("key"); public static final Order KEY_ASC = Order.asc("key");




+ 9
- 5
bubble-server/src/main/java/bubble/dao/device/DeviceDAO.java View File

@@ -46,6 +46,7 @@ public class DeviceDAO extends AccountOwnedEntityDAO<Device> {
@Autowired private BubbleConfiguration configuration; @Autowired private BubbleConfiguration configuration;
@Autowired private AppDataDAO dataDAO; @Autowired private AppDataDAO dataDAO;
@Autowired private TrustedClientDAO trustDAO; @Autowired private TrustedClientDAO trustDAO;
@Autowired private FlexRouterDAO flexRouterDAO;
@Autowired private DeviceService deviceService; @Autowired private DeviceService deviceService;


@Override public Order getDefaultSortOrder() { return ORDER_CTIME_ASC; } @Override public Order getDefaultSortOrder() { return ORDER_CTIME_ASC; }
@@ -134,21 +135,24 @@ public class DeviceDAO extends AccountOwnedEntityDAO<Device> {
final Device device = findByUuid(uuid); final Device device = findByUuid(uuid);
if (device != null) { if (device != null) {
if (device.uninitialized()) die("Cannot delete special device: " + device.getName()); if (device.uninitialized()) die("Cannot delete special device: " + device.getName());

dataDAO.deleteDevice(uuid);
trustDAO.deleteDevice(uuid);
deleteDeviceDependencies(uuid);
super.delete(uuid); super.delete(uuid);
refreshVpnUsers(); refreshVpnUsers();
} }
} }


@Override public void forceDelete(String uuid) { @Override public void forceDelete(String uuid) {
dataDAO.deleteDevice(uuid);
trustDAO.deleteDevice(uuid);
deleteDeviceDependencies(uuid);
super.delete(uuid); super.delete(uuid);
refreshVpnUsers(); refreshVpnUsers();
} }


private void deleteDeviceDependencies(String uuid) {
dataDAO.deleteDevice(uuid);
trustDAO.deleteDevice(uuid);
flexRouterDAO.deleteDevice(uuid);
}

@Transactional @Transactional
public synchronized boolean ensureAllSpareDevices(@NonNull final String account, @NonNull final String network) { public synchronized boolean ensureAllSpareDevices(@NonNull final String account, @NonNull final String network) {
if (configuration.isSage()) return true; if (configuration.isSage()) return true;


+ 10
- 1
bubble-server/src/main/java/bubble/dao/device/FlexRouterDAO.java View File

@@ -19,7 +19,7 @@ import static org.cobbzilla.wizard.resources.ResourceUtil.invalidEx;
import static org.hibernate.criterion.Restrictions.*; import static org.hibernate.criterion.Restrictions.*;


@Repository @Slf4j @Repository @Slf4j
public class FlexRouterDAO extends AccountOwnedEntityDAO<FlexRouter> {
public class FlexRouterDAO extends AccountOwnedEntityDAO<FlexRouter> implements HasDeviceDAO {


@Autowired private FlexRouterService flexRouterService; @Autowired private FlexRouterService flexRouterService;


@@ -80,4 +80,13 @@ public class FlexRouterDAO extends AccountOwnedEntityDAO<FlexRouter> {


public FlexRouter findByKeyHash(String keyHash) { return findByUniqueField("keyHash", keyHash); } public FlexRouter findByKeyHash(String keyHash) { return findByUniqueField("keyHash", keyHash); }


@Override public void deleteDevice(String uuid) {
final int count = bulkDelete("device", uuid);
if (count <= 1) {
log.info("deleteDevice: deleted "+count+" TrustedClient records for device "+uuid);
} else {
log.warn("deleteDevice: deleted "+count+" TrustedClient records (expected only 1) for device "+uuid);
}
}

} }

+ 7
- 0
bubble-server/src/main/java/bubble/dao/device/HasDeviceDAO.java View File

@@ -0,0 +1,7 @@
package bubble.dao.device;

public interface HasDeviceDAO {

void deleteDevice(String uuid);

}

+ 6
- 5
bubble-server/src/main/java/bubble/resources/account/MeResource.java View File

@@ -15,10 +15,10 @@ import bubble.model.account.AuthenticatorRequest;
import bubble.model.account.message.AccountMessage; import bubble.model.account.message.AccountMessage;
import bubble.model.account.message.AccountMessageType; import bubble.model.account.message.AccountMessageType;
import bubble.model.account.message.ActionTarget; import bubble.model.account.message.ActionTarget;
import bubble.model.device.BubbleDeviceType;
import bubble.resources.app.AppsResource; import bubble.resources.app.AppsResource;
import bubble.resources.bill.*; import bubble.resources.bill.*;
import bubble.resources.cloud.*; import bubble.resources.cloud.*;
import bubble.resources.device.DeviceTypesResource;
import bubble.resources.device.DevicesResource; import bubble.resources.device.DevicesResource;
import bubble.resources.device.FlexRoutersResource; import bubble.resources.device.FlexRoutersResource;
import bubble.resources.driver.DriversResource; import bubble.resources.driver.DriversResource;
@@ -28,10 +28,10 @@ import bubble.server.BubbleConfiguration;
import bubble.service.account.StandardAccountMessageService; import bubble.service.account.StandardAccountMessageService;
import bubble.service.account.StandardAuthenticatorService; import bubble.service.account.StandardAuthenticatorService;
import bubble.service.account.download.AccountDownloadService; import bubble.service.account.download.AccountDownloadService;
import bubble.service.upgrade.BubbleJarUpgradeService;
import bubble.service.boot.BubbleModelSetupService; import bubble.service.boot.BubbleModelSetupService;
import bubble.service.boot.SageHelloService; import bubble.service.boot.SageHelloService;
import bubble.service.cloud.NodeLaunchMonitor; import bubble.service.cloud.NodeLaunchMonitor;
import bubble.service.upgrade.BubbleJarUpgradeService;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import lombok.Cleanup; import lombok.Cleanup;
import lombok.Getter; import lombok.Getter;
@@ -368,9 +368,10 @@ public class MeResource {
return configuration.subResource(DevicesResource.class, caller); return configuration.subResource(DevicesResource.class, caller);
} }


@GET @Path(EP_DEVICE_TYPES)
public Response getDeviceTypes(@Context ContainerRequest ctx) {
return ok(BubbleDeviceType.getSelectableTypes());
@Path(EP_DEVICE_TYPES)
public DeviceTypesResource getDeviceTypes(@Context ContainerRequest ctx) {
final Account caller = userPrincipal(ctx);
return configuration.subResource(DeviceTypesResource.class, caller);
} }


@Path(EP_FLEX_ROUTERS) @Path(EP_FLEX_ROUTERS)


+ 60
- 0
bubble-server/src/main/java/bubble/resources/device/DeviceTypesResource.java View File

@@ -0,0 +1,60 @@
package bubble.resources.device;

import bubble.model.account.Account;
import bubble.model.device.BubbleDeviceType;
import bubble.model.device.DeviceSecurityLevel;
import bubble.service.device.DeviceService;
import lombok.extern.slf4j.Slf4j;
import org.glassfish.jersey.server.ContainerRequest;
import org.springframework.beans.factory.annotation.Autowired;

import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import java.util.HashMap;
import java.util.Map;

import static bubble.ApiConstants.EP_DEFAULT_SECURITY_LEVEL;
import static org.cobbzilla.util.http.HttpContentTypes.APPLICATION_JSON;
import static org.cobbzilla.wizard.resources.ResourceUtil.*;

@Produces(APPLICATION_JSON)
@Consumes(APPLICATION_JSON)
@Slf4j
public class DeviceTypesResource {

@Autowired private DeviceService deviceService;

private Account account;

public DeviceTypesResource (Account account) { this.account = account; }

@GET
public Response getDeviceTypes (@Context ContainerRequest ctx) {
return ok(BubbleDeviceType.getSelectableTypes());
}

@GET @Path(EP_DEFAULT_SECURITY_LEVEL)
public Response getDefaultSecurityLevels (@Context ContainerRequest ctx) {
return ok(getDefaultSecurityLevels());
}

public Map<BubbleDeviceType, DeviceSecurityLevel> getDefaultSecurityLevels() {
final Map<BubbleDeviceType, DeviceSecurityLevel> levels = new HashMap<>();
for (BubbleDeviceType type : BubbleDeviceType.getSelectableTypes()) {
levels.put(type, deviceService.getDefaultSecurityLevel(type));
}
return levels;
}

@POST @Path(EP_DEFAULT_SECURITY_LEVEL+"/{deviceType}/{level}")
public Response setDefaultSecurityLevel (@Context ContainerRequest ctx,
@PathParam("deviceType") BubbleDeviceType type,
@PathParam("level") DeviceSecurityLevel level) {
final Account caller = userPrincipal(ctx);
if (!caller.admin()) return forbidden();
deviceService.setDefaultSecurityLevel(type, level);
return ok(getDefaultSecurityLevels());
}

}

+ 3
- 2
bubble-server/src/main/java/bubble/resources/device/DevicesResource.java View File

@@ -86,8 +86,9 @@ public class DevicesResource extends AccountOwnedResource<Device, DeviceDAO> {
device.initTotpKey(); device.initTotpKey();
} }


log.info("setReferences: no securityLevel, setting to default for type "+device.getDeviceType()+": "+device.getDeviceType().getDefaultSecurityLevel());
if (!device.hasSecurityLevel()) device.setSecurityLevel(device.getDeviceType().getDefaultSecurityLevel());
final DeviceSecurityLevel defaultSecurityLevel = deviceService.getDefaultSecurityLevel(device.getDeviceType());
log.info("setReferences: no securityLevel, setting to default for type "+device.getDeviceType()+": "+ defaultSecurityLevel);
if (!device.hasSecurityLevel()) device.setSecurityLevel(defaultSecurityLevel);


return super.setReferences(ctx, caller, device); return super.setReferences(ctx, caller, device);
} }


+ 5
- 0
bubble-server/src/main/java/bubble/service/device/DeviceService.java View File

@@ -5,7 +5,9 @@
package bubble.service.device; package bubble.service.device;


import bubble.model.account.Account; import bubble.model.account.Account;
import bubble.model.device.BubbleDeviceType;
import bubble.model.device.Device; import bubble.model.device.Device;
import bubble.model.device.DeviceSecurityLevel;
import bubble.model.device.DeviceStatus; import bubble.model.device.DeviceStatus;


import java.util.List; import java.util.List;
@@ -28,4 +30,7 @@ public interface DeviceService {
DeviceStatus getDeviceStatus(String deviceUuid); DeviceStatus getDeviceStatus(String deviceUuid);
DeviceStatus getLiveDeviceStatus(String deviceUuid); DeviceStatus getLiveDeviceStatus(String deviceUuid);


default DeviceSecurityLevel getDefaultSecurityLevel(BubbleDeviceType type) { return type.getDefaultSecurityLevel(); }
default void setDefaultSecurityLevel(BubbleDeviceType type, DeviceSecurityLevel level) {}

} }

+ 24
- 0
bubble-server/src/main/java/bubble/service/device/StandardDeviceService.java View File

@@ -9,11 +9,14 @@ import bubble.dao.app.AppSiteDAO;
import bubble.dao.device.DeviceDAO; import bubble.dao.device.DeviceDAO;
import bubble.model.account.Account; import bubble.model.account.Account;
import bubble.model.app.AppSite; import bubble.model.app.AppSite;
import bubble.model.device.BubbleDeviceType;
import bubble.model.device.Device; import bubble.model.device.Device;
import bubble.model.device.DeviceSecurityLevel;
import bubble.model.device.DeviceStatus; import bubble.model.device.DeviceStatus;
import bubble.server.BubbleConfiguration; import bubble.server.BubbleConfiguration;
import bubble.service.cloud.GeoService; import bubble.service.cloud.GeoService;
import bubble.service.stream.StandardRuleEngineService; import bubble.service.stream.StandardRuleEngineService;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.cobbzilla.util.collection.ExpirationMap; import org.cobbzilla.util.collection.ExpirationMap;
import org.cobbzilla.util.collection.SingletonList; import org.cobbzilla.util.collection.SingletonList;
@@ -48,6 +51,8 @@ public class StandardDeviceService implements DeviceService {


public static final String DEVICE_FILE_PREFIX = "device_"; public static final String DEVICE_FILE_PREFIX = "device_";


public static final String REDIS_DEFAULT_SECURITY_LEVEL_PREFIX = "bubble_default_device_security_level";

// used in dnscrypt-proxy and mitmproxy to check device security level // used in dnscrypt-proxy and mitmproxy to check device security level
public static final String REDIS_KEY_DEVICE_SECURITY_LEVEL_PREFIX = "bubble_device_security_level_"; public static final String REDIS_KEY_DEVICE_SECURITY_LEVEL_PREFIX = "bubble_device_security_level_";
public static final String REDIS_KEY_DEVICE_SITE_MAX_SECURITY_LEVEL_PREFIX = "bubble_device_site_max_security_level_"; public static final String REDIS_KEY_DEVICE_SITE_MAX_SECURITY_LEVEL_PREFIX = "bubble_device_site_max_security_level_";
@@ -76,6 +81,25 @@ public class StandardDeviceService implements DeviceService {


private final Map<String, Device> deviceCache = new ExpirationMap<>(MINUTES.toMillis(10)); private final Map<String, Device> deviceCache = new ExpirationMap<>(MINUTES.toMillis(10));


@Getter(lazy=true) private final RedisService defaultSecurityLevelCache = redis.prefixNamespace(REDIS_DEFAULT_SECURITY_LEVEL_PREFIX);

@Override public DeviceSecurityLevel getDefaultSecurityLevel(BubbleDeviceType type) {
final String defaultLevel = getDefaultSecurityLevelCache().get(type.name());
final DeviceSecurityLevel regularDefault = type.getDefaultSecurityLevel();
if (defaultLevel != null) {
try {
return DeviceSecurityLevel.fromString(defaultLevel);
} catch (Exception e) {
log.error("getDefaultSecurityLevel("+type+") returned invalid value (using default="+regularDefault+"): "+defaultLevel);
}
}
return regularDefault;
}

@Override public void setDefaultSecurityLevel(BubbleDeviceType type, DeviceSecurityLevel level) {
getDefaultSecurityLevelCache().set(type.name(), level.name());
}

@Override public Device findDeviceByIp (String ipAddr) { @Override public Device findDeviceByIp (String ipAddr) {


if (!WG_DEVICES_DIR.exists()) { if (!WG_DEVICES_DIR.exists()) {


+ 1
- 1
bubble-server/src/main/resources/META-INF/bubble/bubble.properties View File

@@ -1 +1 @@
bubble.version=Adventure 1.2.5
bubble.version=Adventure 1.2.6

Loading…
Cancel
Save