Browse Source

WIP. adding flex routing

pull/51/head
Jonathan Cobb 4 years ago
parent
commit
f7b3f9cd2a
26 changed files with 310 additions and 65 deletions
  1. +7
    -2
      bubble-server/src/main/java/bubble/ApiConstants.java
  2. +2
    -2
      bubble-server/src/main/java/bubble/dao/account/AccountDAO.java
  3. +2
    -2
      bubble-server/src/main/java/bubble/dao/app/AppSiteDAO.java
  4. +4
    -4
      bubble-server/src/main/java/bubble/dao/device/DeviceDAO.java
  5. +21
    -0
      bubble-server/src/main/java/bubble/dao/device/FlexRouterDAO.java
  6. +84
    -0
      bubble-server/src/main/java/bubble/model/device/FlexRouter.java
  7. +1
    -0
      bubble-server/src/main/java/bubble/resources/account/AccountsResource.java
  8. +3
    -3
      bubble-server/src/main/java/bubble/resources/account/AuthResource.java
  9. +8
    -0
      bubble-server/src/main/java/bubble/resources/account/MeResource.java
  10. +3
    -3
      bubble-server/src/main/java/bubble/resources/app/AppSitesResource.java
  11. +3
    -3
      bubble-server/src/main/java/bubble/resources/app/AppsResource.java
  12. +8
    -6
      bubble-server/src/main/java/bubble/resources/device/DevicesResource.java
  13. +62
    -0
      bubble-server/src/main/java/bubble/resources/device/FlexRoutersResource.java
  14. +8
    -8
      bubble-server/src/main/java/bubble/resources/stream/FilterHttpResource.java
  15. +3
    -3
      bubble-server/src/main/java/bubble/resources/stream/ReverseProxyResource.java
  16. +2
    -2
      bubble-server/src/main/java/bubble/rule/AbstractAppRuleDriver.java
  17. +6
    -6
      bubble-server/src/main/java/bubble/rule/bblock/BubbleBlockRuleDriver.java
  18. +4
    -2
      bubble-server/src/main/java/bubble/server/listener/NodeInitializerListener.java
  19. +8
    -7
      bubble-server/src/main/java/bubble/service/dbfilter/FilteredEntityIterator.java
  20. +2
    -2
      bubble-server/src/main/java/bubble/service/device/DeviceService.java
  21. +58
    -0
      bubble-server/src/main/java/bubble/service/device/FlexRouterService.java
  22. +3
    -2
      bubble-server/src/main/java/bubble/service/device/StandardDeviceService.java
  23. +4
    -4
      bubble-server/src/main/java/bubble/service/stream/StandardAppPrimerService.java
  24. +2
    -2
      bubble-server/src/main/java/bubble/service_dbfilter/DbFilterDeviceService.java
  25. +1
    -1
      bubble-server/src/main/resources/messages
  26. +1
    -1
      utils/cobbzilla-wizard

+ 7
- 2
bubble-server/src/main/java/bubble/ApiConstants.java View File

@@ -176,6 +176,7 @@ public class ApiConstants {
public static final String EP_NODES = "/nodes";
public static final String EP_DEVICES = "/devices";
public static final String EP_DEVICE_TYPES = "/deviceTypes";
public static final String EP_FLEX_ROUTERS = "/flexRouters";
public static final String EP_MODEL = "/model";
public static final String EP_VPN = "/vpn";
public static final String EP_IPS = "/ips";
@@ -276,8 +277,7 @@ public class ApiConstants {
}

public static String getRemoteHost(Request req) {
final String xff = req.getHeader("X-Forwarded-For");
final String remoteHost = xff == null ? req.getRemoteAddr() : xff;
final String remoteHost = getRemoteAddr(req);
if (isPublicIpv4(remoteHost)) return remoteHost;
final String publicIp = getFirstPublicIpv4();
if (publicIp != null) return publicIp;
@@ -285,6 +285,11 @@ public class ApiConstants {
return isPublicIpv4(externalIp) ? externalIp : remoteHost;
}

public static String getRemoteAddr(Request req) {
final String xff = req.getHeader("X-Forwarded-For");
return xff == null ? req.getRemoteAddr() : xff;
}

public static String getUserAgent(ContainerRequest ctx) { return ctx.getHeaderString(USER_AGENT); }
public static String getReferer(ContainerRequest ctx) { return ctx.getHeaderString(REFERER); }



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

@@ -23,7 +23,7 @@ import bubble.server.BubbleConfiguration;
import bubble.service.SearchService;
import bubble.service.account.SyncPasswordService;
import bubble.service.boot.SelfNodeService;
import bubble.service.cloud.DeviceIdService;
import bubble.service.device.DeviceService;
import bubble.service.stream.RuleEngineService;
import lombok.Getter;
import lombok.NonNull;
@@ -78,7 +78,7 @@ public class AccountDAO extends AbstractCRUDDAO<Account> implements SqlViewSearc
@Autowired private SearchService searchService;
@Autowired private SyncPasswordService syncPasswordService;
@Autowired private ReferralCodeDAO referralCodeDAO;
@Autowired private DeviceIdService deviceService;
@Autowired private DeviceService deviceService;
@Autowired private RuleEngineService ruleEngineService;

public Account newAccount(Request req, Account caller, AccountRegistration request, Account parent) {


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

@@ -5,7 +5,7 @@
package bubble.dao.app;

import bubble.model.app.AppSite;
import bubble.service.cloud.DeviceIdService;
import bubble.service.device.DeviceService;
import bubble.service.stream.RuleEngineService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
@@ -14,7 +14,7 @@ import org.springframework.stereotype.Repository;
public class AppSiteDAO extends AppTemplateEntityDAO<AppSite> {

@Autowired private RuleEngineService ruleEngineService;
@Autowired private DeviceIdService deviceService;
@Autowired private DeviceService deviceService;

@Override public AppSite postCreate(AppSite site, Object context) {
// todo: update entities based on this template if account has updates enabled


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

@@ -11,7 +11,7 @@ import bubble.dao.app.AppDataDAO;
import bubble.model.device.BubbleDeviceType;
import bubble.model.device.Device;
import bubble.server.BubbleConfiguration;
import bubble.service.cloud.DeviceIdService;
import bubble.service.device.DeviceService;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.criterion.Order;
@@ -46,7 +46,7 @@ public class DeviceDAO extends AccountOwnedEntityDAO<Device> {
@Autowired private BubbleConfiguration configuration;
@Autowired private AppDataDAO dataDAO;
@Autowired private TrustedClientDAO trustDAO;
@Autowired private DeviceIdService deviceIdService;
@Autowired private DeviceService deviceService;

@Override public Order getDefaultSortOrder() { return ORDER_CTIME_ASC; }

@@ -113,7 +113,7 @@ public class DeviceDAO extends AccountOwnedEntityDAO<Device> {
result = super.update(uninitialized);
}

deviceIdService.setDeviceSecurityLevel(result);
deviceService.setDeviceSecurityLevel(result);
return result;
}
}
@@ -125,7 +125,7 @@ public class DeviceDAO extends AccountOwnedEntityDAO<Device> {

toUpdate.update(updateRequest);
final var updated = super.update(toUpdate);
deviceIdService.setDeviceSecurityLevel(updated);
deviceService.setDeviceSecurityLevel(updated);
refreshVpnUsers();
return updated;
}


+ 21
- 0
bubble-server/src/main/java/bubble/dao/device/FlexRouterDAO.java View File

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

import bubble.dao.account.AccountOwnedEntityDAO;
import bubble.model.device.FlexRouter;
import org.springframework.stereotype.Repository;

import java.util.List;

import static org.hibernate.criterion.Restrictions.*;

@Repository
public class FlexRouterDAO extends AccountOwnedEntityDAO<FlexRouter> {

public List<FlexRouter> findEnabledAndRegistered() {
return list(criteria().add(and(
eq("enabled", true),
ne("port", 0),
isNotNull("token"))));
}

}

+ 84
- 0
bubble-server/src/main/java/bubble/model/device/FlexRouter.java View File

@@ -0,0 +1,84 @@
package bubble.model.device;

import bubble.model.account.Account;
import bubble.model.account.HasAccountNoName;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.map.SingletonMap;
import org.cobbzilla.wizard.model.Identifiable;
import org.cobbzilla.wizard.model.IdentifiableBase;
import org.cobbzilla.wizard.model.entityconfig.EntityFieldMode;
import org.cobbzilla.wizard.model.entityconfig.EntityFieldType;
import org.cobbzilla.wizard.model.entityconfig.annotations.*;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Transient;

import static bubble.ApiConstants.EP_FLEX_ROUTERS;
import static org.cobbzilla.util.daemon.ZillaRuntime.*;
import static org.cobbzilla.util.json.JsonUtil.json;
import static org.cobbzilla.util.reflect.ReflectionUtil.copy;

@Entity
@ECType(root=true) @ToString(of={"ip", "port"})
@ECTypeURIs(baseURI=EP_FLEX_ROUTERS, listFields={"name", "enabled"})
@NoArgsConstructor @Accessors(chain=true) @Slf4j
@ECIndexes({ @ECIndex(unique=true, of={"account", "ip"}) })
public class FlexRouter extends IdentifiableBase implements HasAccountNoName {

public static final String[] CREATE_FIELDS = { "ip", "enabled" };
public static final String[] UPDATE_FIELDS = { "enabled" };

public FlexRouter (FlexRouter other) { copy(this, other, CREATE_FIELDS); }

@Override public Identifiable update(Identifiable other) { copy(this, other, UPDATE_FIELDS); return this; }

@ECSearchable(filter=true) @ECField(index=10)
@ECIndex @Column(nullable=false, length=500)
@Getter @Setter private String ip;

@ECSearchable(filter=true) @ECField(index=20)
@ECIndex @Column(nullable=false)
@JsonIgnore @Getter @Setter private Integer port = 0;

public String id () { return getIp() + "/" + getUuid(); }

@ECSearchable @ECField(index=30)
@ECForeignKey(entity=Account.class)
@Column(nullable=false, updatable=false, length=UUID_MAXLEN)
@Getter @Setter private String account;

@ECSearchable @ECField(index=40)
@ECIndex @Column(nullable=false)
@Getter @Setter private Boolean enabled = true;
public boolean enabled () { return bool(enabled); }

@ECSearchable @ECField(index=50)
@ECIndex @Column(nullable=false)
@Getter @Setter private Boolean active = true;
public boolean active() { return bool(active); }

@ECSearchable @ECField(index=60, type=EntityFieldType.epoch_time, mode=EntityFieldMode.readOnly)
@Getter @Setter private Long lastSeen;
public FlexRouter setLastSeen () { return setLastSeen(now()); }

@JsonIgnore @Transient public long getAge () { return lastSeen == null ? Long.MAX_VALUE : now() - lastSeen; }

@ECSearchable(filter=true) @ECField(index=70)
@ECIndex @Column(length=100)
@JsonIgnore @Getter @Setter private String token;
public boolean hasToken () { return !empty(token); }

@Transient @Getter @Setter private String serverToken;

public String pingUrl() { return "http://" + getIp() + ":" + getPort() + "/ping"; }

public String pingObject() { return json(new SingletonMap("token", getToken())); }

}

+ 1
- 0
bubble-server/src/main/java/bubble/resources/account/AccountsResource.java View File

@@ -19,6 +19,7 @@ import bubble.model.device.BubbleDeviceType;
import bubble.resources.app.AppsResource;
import bubble.resources.bill.*;
import bubble.resources.cloud.*;
import bubble.resources.device.DevicesResource;
import bubble.resources.driver.DriversResource;
import bubble.resources.notify.ReceivedNotificationsResource;
import bubble.resources.notify.SentNotificationsResource;


+ 3
- 3
bubble-server/src/main/java/bubble/resources/account/AuthResource.java View File

@@ -32,7 +32,7 @@ import bubble.service.bill.PromotionService;
import bubble.service.boot.ActivationService;
import bubble.service.boot.NodeManagerService;
import bubble.service.boot.SageHelloService;
import bubble.service.cloud.DeviceIdService;
import bubble.service.device.DeviceService;
import bubble.service.cloud.GeoService;
import bubble.service.notify.NotificationService;
import bubble.service.upgrade.BubbleJarUpgradeService;
@@ -97,7 +97,7 @@ public class AuthResource {
@Autowired private BubbleConfiguration configuration;
@Autowired private StandardAuthenticatorService authenticatorService;
@Autowired private PromotionService promoService;
@Autowired private DeviceIdService deviceIdService;
@Autowired private DeviceService deviceService;
@Autowired private DeviceDAO deviceDAO;
@Autowired private BubbleNodeKeyDAO nodeKeyDAO;
@Autowired private NodeManagerService nodeManagerService;
@@ -675,7 +675,7 @@ public class AuthResource {
} else {
final String remoteHost = getRemoteHost(req);
if (!empty(remoteHost)) {
final Device device = deviceIdService.findDeviceByIp(remoteHost);
final Device device = deviceService.findDeviceByIp(remoteHost);
if (device != null) {
type = device.getDeviceType().getCertType();
}


+ 8
- 0
bubble-server/src/main/java/bubble/resources/account/MeResource.java View File

@@ -19,6 +19,8 @@ import bubble.model.device.BubbleDeviceType;
import bubble.resources.app.AppsResource;
import bubble.resources.bill.*;
import bubble.resources.cloud.*;
import bubble.resources.device.DevicesResource;
import bubble.resources.device.FlexRoutersResource;
import bubble.resources.driver.DriversResource;
import bubble.resources.notify.ReceivedNotificationsResource;
import bubble.resources.notify.SentNotificationsResource;
@@ -371,6 +373,12 @@ public class MeResource {
return ok(BubbleDeviceType.getSelectableTypes());
}

@Path(EP_FLEX_ROUTERS)
public FlexRoutersResource getFlexRouters(@Context ContainerRequest ctx) {
final Account caller = userPrincipal(ctx);
return configuration.subResource(FlexRoutersResource.class, caller);
}

@Path(EP_REFERRAL_CODES)
public ReferralCodesResource getReferralCodes(@Context ContainerRequest ctx) {
final Account caller = userPrincipal(ctx);


+ 3
- 3
bubble-server/src/main/java/bubble/resources/app/AppSitesResource.java View File

@@ -12,7 +12,7 @@ import bubble.model.app.config.AppDataDriver;
import bubble.model.app.config.AppDataView;
import bubble.model.device.Device;
import bubble.resources.account.AccountOwnedTemplateResource;
import bubble.service.cloud.DeviceIdService;
import bubble.service.device.DeviceService;
import org.cobbzilla.wizard.model.search.SearchQuery;
import org.glassfish.grizzly.http.server.Request;
import org.glassfish.jersey.server.ContainerRequest;
@@ -32,7 +32,7 @@ public class AppSitesResource extends AccountOwnedTemplateResource<AppSite, AppS

private final BubbleApp app;

@Autowired private DeviceIdService deviceIdService;
@Autowired private DeviceService deviceService;

public AppSitesResource(Account account, BubbleApp app) {
super(account);
@@ -102,7 +102,7 @@ public class AppSitesResource extends AccountOwnedTemplateResource<AppSite, AppS
if (view == null) return notFound(viewName);

final String remoteHost = getRemoteHost(req);
final Device device = deviceIdService.findDeviceByIp(remoteHost);
final Device device = deviceService.findDeviceByIp(remoteHost);

final AppDataDriver driver = app.getDataConfig().getDataDriver(configuration);
return ok(driver.query(caller, device, app, site, view, query));


+ 3
- 3
bubble-server/src/main/java/bubble/resources/app/AppsResource.java View File

@@ -9,7 +9,7 @@ import bubble.model.app.BubbleApp;
import bubble.model.app.config.AppDataDriver;
import bubble.model.app.config.AppDataView;
import bubble.model.device.Device;
import bubble.service.cloud.DeviceIdService;
import bubble.service.device.DeviceService;
import lombok.extern.slf4j.Slf4j;
import org.cobbzilla.wizard.model.search.SearchQuery;
import org.glassfish.grizzly.http.server.Request;
@@ -29,7 +29,7 @@ public class AppsResource extends AppsResourceBase {

public AppsResource(Account account) { super(account); }

@Autowired private DeviceIdService deviceIdService;
@Autowired private DeviceService deviceService;

@GET @Path("/{id}"+EP_VIEW+"/{view}")
public Response search(@Context Request req,
@@ -58,7 +58,7 @@ public class AppsResource extends AppsResourceBase {
if (view == null) return notFound(viewName);

final String remoteHost = getRemoteHost(req);
final Device device = deviceIdService.findDeviceByIp(remoteHost);
final Device device = deviceService.findDeviceByIp(remoteHost);

final AppDataDriver driver = app.getDataConfig().getDataDriver(configuration);
return ok(driver.query(caller, device, app, null, view, query));


bubble-server/src/main/java/bubble/resources/account/DevicesResource.java → bubble-server/src/main/java/bubble/resources/device/DevicesResource.java View File

@@ -2,14 +2,16 @@
* Copyright (c) 2020 Bubble, Inc. All rights reserved.
* For personal (non-commercial) use, see license: https://getbubblenow.com/bubble-license/
*/
package bubble.resources.account;
package bubble.resources.device;

import bubble.dao.device.DeviceDAO;
import bubble.model.account.Account;
import bubble.model.device.Device;
import bubble.model.device.DeviceSecurityLevel;
import bubble.resources.account.AccountOwnedResource;
import bubble.resources.account.VpnConfigResource;
import bubble.server.BubbleConfiguration;
import bubble.service.cloud.DeviceIdService;
import bubble.service.device.DeviceService;
import lombok.extern.slf4j.Slf4j;
import org.glassfish.grizzly.http.server.Request;
import org.glassfish.jersey.server.ContainerRequest;
@@ -53,7 +55,7 @@ public class DevicesResource extends AccountOwnedResource<Device, DeviceDAO> {
}

@Override protected Device populate(ContainerRequest ctx, Device device) {
return device.setStatus(deviceIdService.getDeviceStatus(device.getUuid()));
return device.setStatus(deviceService.getDeviceStatus(device.getUuid()));
}

@Override protected List<Device> sort(List<Device> list, Request req, ContainerRequest ctx) {
@@ -106,14 +108,14 @@ public class DevicesResource extends AccountOwnedResource<Device, DeviceDAO> {
return configuration.subResource(VpnConfigResource.class, device);
}

@Autowired private DeviceIdService deviceIdService;
@Autowired private DeviceService deviceService;

@GET @Path("/{id}"+EP_IPS)
public Response getIps(@Context ContainerRequest ctx,
@PathParam("id") String id) {
final Device device = getDao().findByAccountAndId(getAccountUuid(ctx), id);
if (device == null) return notFound(id);
return ok(deviceIdService.findIpsByDevice(device.getUuid()));
return ok(deviceService.findIpsByDevice(device.getUuid()));
}

@GET @Path("/{id}"+EP_STATUS)
@@ -121,7 +123,7 @@ public class DevicesResource extends AccountOwnedResource<Device, DeviceDAO> {
@PathParam("id") String id) {
final Device device = getDao().findByAccountAndId(getAccountUuid(ctx), id);
if (device == null) return notFound(id);
return ok(deviceIdService.getLiveDeviceStatus(device.getUuid()));
return ok(deviceService.getLiveDeviceStatus(device.getUuid()));
}

}

+ 62
- 0
bubble-server/src/main/java/bubble/resources/device/FlexRoutersResource.java View File

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

import bubble.dao.device.FlexRouterDAO;
import bubble.model.account.Account;
import bubble.model.device.Device;
import bubble.model.device.FlexRouter;
import bubble.resources.account.AccountOwnedResource;
import bubble.service.device.DeviceService;
import lombok.extern.slf4j.Slf4j;
import org.glassfish.grizzly.http.server.Request;
import org.glassfish.jersey.server.ContainerRequest;
import org.springframework.beans.factory.annotation.Autowired;

import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;

import static bubble.ApiConstants.EP_REGISTER;
import static bubble.ApiConstants.getRemoteAddr;
import static org.apache.commons.lang3.RandomStringUtils.randomAlphanumeric;
import static org.cobbzilla.wizard.resources.ResourceUtil.*;

@Slf4j
public class FlexRoutersResource extends AccountOwnedResource<FlexRouter, FlexRouterDAO> {

@Autowired private DeviceService deviceService;

public FlexRoutersResource(Account account) { super(account); }

@Override protected boolean isReadOnly(ContainerRequest ctx) {
final Account caller = userPrincipal(ctx);
return !caller.admin();
}

@POST @Path("{id}"+EP_REGISTER)
public Response register(@Context Request req,
@Context ContainerRequest ctx,
@PathParam("id") String id,
FlexRouter request) {
// caller must be admin
if (isReadOnly(ctx)) return forbidden();

// caller must come from a valid device
final String remoteAddr = getRemoteAddr(req);
final Device device = deviceService.findDeviceByIp(remoteAddr);
if (device == null) return invalid("err.device.notFound");

final FlexRouter flexRouter = getDao().findByUuid(id);
if (flexRouter == null) return notFound(id);

// set token and return
final String token = randomAlphanumeric(50);
final FlexRouter updated = getDao().update(flexRouter
.setPort(request.getPort())
.setLastSeen()
.setToken(token));
return ok(updated.setServerToken(token));
}

}

+ 8
- 8
bubble-server/src/main/java/bubble/resources/stream/FilterHttpResource.java View File

@@ -24,7 +24,7 @@ import bubble.server.BubbleConfiguration;
import bubble.service.block.BlockStatsService;
import bubble.service.block.BlockStatsSummary;
import bubble.service.boot.SelfNodeService;
import bubble.service.cloud.DeviceIdService;
import bubble.service.device.DeviceService;
import bubble.service.stream.ConnectionCheckResponse;
import bubble.service.stream.StandardRuleEngineService;
import com.fasterxml.jackson.databind.JsonNode;
@@ -79,7 +79,7 @@ public class FilterHttpResource {
@Autowired private AppSiteDAO siteDAO;
@Autowired private AppRuleDAO ruleDAO;
@Autowired private DeviceDAO deviceDAO;
@Autowired private DeviceIdService deviceIdService;
@Autowired private DeviceService deviceService;
@Autowired private RedisService redis;
@Autowired private BubbleConfiguration configuration;
@Autowired private SelfNodeService selfNodeService;
@@ -163,7 +163,7 @@ public class FilterHttpResource {
}

final String vpnAddr = connCheckRequest.getRemoteAddr();
final Device device = deviceIdService.findDeviceByIp(vpnAddr);
final Device device = deviceService.findDeviceByIp(vpnAddr);
if (device == null) {
if (log.isDebugEnabled()) log.debug(prefix+"device not found for IP "+vpnAddr+", returning not found");
return notFound();
@@ -237,17 +237,17 @@ public class FilterHttpResource {
@Getter(lazy=true) private final BubbleNetwork thisNetwork = selfNodeService.getThisNetwork();

public boolean showStats(String accountUuid, String ip, String[] fqdns) {
if (!deviceIdService.doShowBlockStats(accountUuid)) return false;
if (!deviceService.doShowBlockStats(accountUuid)) return false;
for (String fqdn : fqdns) {
final Boolean show = deviceIdService.doShowBlockStatsForIpAndFqdn(ip, fqdn);
final Boolean show = deviceService.doShowBlockStatsForIpAndFqdn(ip, fqdn);
if (show != null) return show;
}
return true;
}

public boolean showStats(String accountUuid, String ip, String fqdn) {
if (!deviceIdService.doShowBlockStats(accountUuid)) return false;
final Boolean show = deviceIdService.doShowBlockStatsForIpAndFqdn(ip, fqdn);
if (!deviceService.doShowBlockStats(accountUuid)) return false;
final Boolean show = deviceService.doShowBlockStatsForIpAndFqdn(ip, fqdn);
return show == null || show;
}

@@ -277,7 +277,7 @@ public class FilterHttpResource {
}

final String vpnAddr = filterRequest.getClientAddr();
final Device device = deviceIdService.findDeviceByIp(vpnAddr);
final Device device = deviceService.findDeviceByIp(vpnAddr);
if (device == null) {
if (log.isDebugEnabled()) log.debug(prefix+"device not found for IP "+vpnAddr+", returning no matchers");
else if (extraLog) log.error(prefix+"device not found for IP "+vpnAddr+", returning no matchers");


+ 3
- 3
bubble-server/src/main/java/bubble/resources/stream/ReverseProxyResource.java View File

@@ -11,7 +11,7 @@ import bubble.model.app.AppMatcher;
import bubble.model.device.Device;
import bubble.rule.FilterMatchDecision;
import bubble.server.BubbleConfiguration;
import bubble.service.cloud.DeviceIdService;
import bubble.service.device.DeviceService;
import bubble.service.stream.StandardRuleEngineService;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
@@ -46,7 +46,7 @@ public class ReverseProxyResource {
@Autowired private AppMatcherDAO matcherDAO;
@Autowired private AppRuleDAO ruleDAO;
@Autowired private StandardRuleEngineService ruleEngine;
@Autowired private DeviceIdService deviceIdService;
@Autowired private DeviceService deviceService;
@Autowired private FilterHttpResource filterHttpResource;

@Getter(lazy=true) private final int prefixLength = configuration.getHttp().getBaseUri().length() + PROXY_ENDPOINT.length() + 1;
@@ -60,7 +60,7 @@ public class ReverseProxyResource {
@PathParam("path") String path) throws URISyntaxException, IOException {
final Account account = userPrincipal(request);
final String remoteHost = getRemoteHost(req);
final Device device = deviceIdService.findDeviceByIp(remoteHost);
final Device device = deviceService.findDeviceByIp(remoteHost);
if (device == null) return ruleEngine.passthru(request);

final URIBean ub = getUriBean(request);


+ 2
- 2
bubble-server/src/main/java/bubble/rule/AbstractAppRuleDriver.java View File

@@ -16,7 +16,7 @@ import bubble.model.device.Device;
import bubble.resources.stream.FilterHttpRequest;
import bubble.resources.stream.FilterMatchersRequest;
import bubble.server.BubbleConfiguration;
import bubble.service.cloud.StandardDeviceIdService;
import bubble.service.device.StandardDeviceService;
import bubble.service.stream.AppPrimerService;
import com.fasterxml.jackson.databind.JsonNode;
import com.github.jknack.handlebars.Handlebars;
@@ -64,7 +64,7 @@ public abstract class AbstractAppRuleDriver implements AppRuleDriver {
@Autowired protected BubbleNetworkDAO networkDAO;
@Autowired protected DeviceDAO deviceDAO;
@Autowired protected AppPrimerService appPrimerService;
@Autowired protected StandardDeviceIdService deviceService;
@Autowired protected StandardDeviceService deviceService;

@Getter @Setter private AppRuleDriver next;



+ 6
- 6
bubble-server/src/main/java/bubble/rule/bblock/BubbleBlockRuleDriver.java View File

@@ -16,7 +16,7 @@ import bubble.rule.RequestModifierConfig;
import bubble.rule.RequestModifierRule;
import bubble.rule.analytics.TrafficAnalyticsRuleDriver;
import bubble.server.BubbleConfiguration;
import bubble.service.cloud.DeviceIdService;
import bubble.service.device.DeviceService;
import bubble.service.stream.AppRuleHarness;
import bubble.service.stream.ConnectionCheckResponse;
import com.fasterxml.jackson.databind.JsonNode;
@@ -419,11 +419,11 @@ public class BubbleBlockRuleDriver extends TrafficAnalyticsRuleDriver
}

@Override public void prime(Account account, BubbleApp app, BubbleConfiguration configuration) {
final DeviceIdService deviceIdService = configuration.getBean(DeviceIdService.class);
final DeviceService deviceService = configuration.getBean(DeviceService.class);
final AppDataDAO dataDAO = configuration.getBean(AppDataDAO.class);
log.info("priming app="+app.getName());
dataDAO.findByAccountAndAppAndAndKeyPrefix(account.getUuid(), app.getUuid(), PREFIX_APPDATA_HIDE_STATS)
.forEach(data -> deviceIdService.setBlockStatsForFqdn(account, fqdnFromKey(data.getKey()), !Boolean.parseBoolean(data.getData())));
.forEach(data -> deviceService.setBlockStatsForFqdn(account, fqdnFromKey(data.getKey()), !Boolean.parseBoolean(data.getData())));
}

@Override public Function<AppData, AppData> createCallback(Account account,
@@ -433,15 +433,15 @@ public class BubbleBlockRuleDriver extends TrafficAnalyticsRuleDriver
final String prefix = "createCallbackB("+data.getKey()+"="+data.getData()+"): ";
log.info(prefix+"starting");
if (data.getKey().startsWith(PREFIX_APPDATA_HIDE_STATS)) {
final DeviceIdService deviceIdService = configuration.getBean(DeviceIdService.class);
final DeviceService deviceService = configuration.getBean(DeviceService.class);
final String fqdn = fqdnFromKey(data.getKey());
if (validateRegexMatches(HOST_PATTERN, fqdn)) {
if (data.deleting()) {
log.info(prefix+"unsetting fqdn: "+fqdn);
deviceIdService.unsetBlockStatsForFqdn(account, fqdn);
deviceService.unsetBlockStatsForFqdn(account, fqdn);
} else {
log.info(prefix+"setting fqdn: "+fqdn);
deviceIdService.setBlockStatsForFqdn(account, fqdn, !Boolean.parseBoolean(data.getData()));
deviceService.setBlockStatsForFqdn(account, fqdn, !Boolean.parseBoolean(data.getData()));
}
} else {
throw invalidEx("err.fqdn.invalid", "not a valid FQDN: "+fqdn, fqdn);


+ 4
- 2
bubble-server/src/main/java/bubble/server/listener/NodeInitializerListener.java View File

@@ -13,8 +13,9 @@ import bubble.model.cloud.BubbleNode;
import bubble.model.cloud.CloudService;
import bubble.server.BubbleConfiguration;
import bubble.service.boot.SelfNodeService;
import bubble.service.cloud.DeviceIdService;
import bubble.service.device.DeviceService;
import bubble.service.cloud.NetworkMonitorService;
import bubble.service.device.FlexRouterService;
import bubble.service.stream.AppDataCleaner;
import bubble.service.stream.AppPrimerService;
import lombok.extern.slf4j.Slf4j;
@@ -112,7 +113,8 @@ public class NodeInitializerListener extends RestServerLifecycleListenerBase<Bub
final BubbleNetwork thisNetwork = c.getThisNetwork();
if (thisNetwork != null && thisNetwork.getInstallType() == AnsibleInstallType.node) {
c.getBean(AppPrimerService.class).primeApps();
c.getBean(DeviceIdService.class).initDeviceSecurityLevels();
c.getBean(FlexRouterService.class).start();
c.getBean(DeviceService.class).initDeviceSecurityLevels();
c.getBean(AppDataCleaner.class).start();
}
}


+ 8
- 7
bubble-server/src/main/java/bubble/service/dbfilter/FilteredEntityIterator.java View File

@@ -24,6 +24,7 @@ import bubble.model.cloud.BubbleNodeKey;
import bubble.model.cloud.notify.ReceivedNotification;
import bubble.model.cloud.notify.SentNotification;
import bubble.model.device.Device;
import bubble.model.device.FlexRouter;
import bubble.server.BubbleConfiguration;
import lombok.extern.slf4j.Slf4j;
import org.cobbzilla.wizard.dao.DAO;
@@ -39,14 +40,14 @@ import static org.cobbzilla.util.daemon.ZillaRuntime.die;
@Slf4j
public class FilteredEntityIterator extends EntityIterator {

private static final List<Class<? extends Identifiable>> POST_COPY_ENTITIES = Arrays.asList(new Class[] {
private static final List<Class<? extends Identifiable>> NO_DEFAULT_COPY_ENTITIES = Arrays.asList(new Class[] {
BubbleNode.class, BubbleNodeKey.class, Device.class, AccountMessage.class,
ReferralCode.class, AccountPayment.class, Bill.class, Promotion.class,
ReceivedNotification.class, SentNotification.class, TrustedClient.class
ReceivedNotification.class, SentNotification.class, TrustedClient.class, FlexRouter.class
});

private static boolean isPostCopyEntity(Class<? extends Identifiable> clazz) {
return POST_COPY_ENTITIES.stream().anyMatch(c -> c.isAssignableFrom(clazz));
private static boolean isNotDefaultCopyEntity(Class<? extends Identifiable> clazz) {
return NO_DEFAULT_COPY_ENTITIES.stream().anyMatch(c -> c.isAssignableFrom(clazz));
}

private final BubbleConfiguration configuration;
@@ -82,10 +83,10 @@ public class FilteredEntityIterator extends EntityIterator {
configuration.getEntityClasses().forEach(c -> {
final DAO dao = configuration.getDaoForEntityClass(c);
if (!AccountOwnedEntityDAO.class.isAssignableFrom(dao.getClass())) {
log.debug("iterate: skipping entity: " + c.getSimpleName());
} else if (isPostCopyEntity(c)) {
log.debug("iterate: skipping entity, not an AccountOwnedEntityDAO: " + c.getSimpleName());
} else if (isNotDefaultCopyEntity(c)) {
log.debug("iterate: skipping " + c.getSimpleName()
+ ", will copy some of these after other objects are copied");
+ ", may copy some of these after default objects are copied");
} else {
// copy entities. this is how the re-keying works (decrypt using current spring config,
// encrypt using new config)


bubble-server/src/main/java/bubble/service/cloud/DeviceIdService.java → bubble-server/src/main/java/bubble/service/device/DeviceService.java View File

@@ -2,7 +2,7 @@
* Copyright (c) 2020 Bubble, Inc. All rights reserved.
* For personal (non-commercial) use, see license: https://getbubblenow.com/bubble-license/
*/
package bubble.service.cloud;
package bubble.service.device;

import bubble.model.account.Account;
import bubble.model.device.Device;
@@ -10,7 +10,7 @@ import bubble.model.device.DeviceStatus;

import java.util.List;

public interface DeviceIdService {
public interface DeviceService {

Device findDeviceByIp(String ip);


+ 58
- 0
bubble-server/src/main/java/bubble/service/device/FlexRouterService.java View File

@@ -0,0 +1,58 @@
package bubble.service.device;

import bubble.dao.device.FlexRouterDAO;
import bubble.model.device.FlexRouter;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.cobbzilla.util.daemon.SimpleDaemon;
import org.cobbzilla.util.http.HttpRequestBean;
import org.cobbzilla.util.http.HttpResponseBean;
import org.cobbzilla.util.http.HttpUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

import static java.util.concurrent.TimeUnit.MINUTES;
import static org.cobbzilla.util.daemon.ZillaRuntime.shortError;
import static org.cobbzilla.util.http.HttpMethods.POST;

@Service @Slf4j
public class FlexRouterService extends SimpleDaemon {

@Getter private final long sleepTime = MINUTES.toMillis(2);

@Autowired private FlexRouterDAO flexRouterDAO;

@Override protected void process() {
try {
final List<FlexRouter> routers = flexRouterDAO.findEnabledAndRegistered();
for (FlexRouter router : routers) {
FlexRouter update = pingRouter(router);
if (update != null) {
flexRouterDAO.update(update);
}
}
} catch (Exception e) {
log.error("process: "+shortError(e));
}
}

private FlexRouter pingRouter(FlexRouter router) {
final String prefix = "pingRouter(" + router + "): ";
final HttpRequestBean request = new HttpRequestBean(POST, router.pingUrl(), router.pingObject());
try {
final HttpResponseBean response = HttpUtil.getResponse(request);
if (!response.isOk()) {
log.error(prefix+"response not OK, marking inactive: "+response);
return router.setActive(false);
}
return router.setActive(true).setLastSeen();

} catch (Exception e) {
log.error(prefix+"error (marking inactive): "+shortError(e));
return router.setActive(false);
}
}

}

bubble-server/src/main/java/bubble/service/cloud/StandardDeviceIdService.java → bubble-server/src/main/java/bubble/service/device/StandardDeviceService.java View File

@@ -2,7 +2,7 @@
* Copyright (c) 2020 Bubble, Inc. All rights reserved.
* For personal (non-commercial) use, see license: https://getbubblenow.com/bubble-license/
*/
package bubble.service.cloud;
package bubble.service.device;

import bubble.dao.account.AccountDAO;
import bubble.dao.app.AppSiteDAO;
@@ -12,6 +12,7 @@ import bubble.model.app.AppSite;
import bubble.model.device.Device;
import bubble.model.device.DeviceStatus;
import bubble.server.BubbleConfiguration;
import bubble.service.cloud.GeoService;
import bubble.service.stream.StandardRuleEngineService;
import lombok.extern.slf4j.Slf4j;
import org.cobbzilla.util.collection.ExpirationMap;
@@ -40,7 +41,7 @@ import static org.cobbzilla.wizard.resources.ResourceUtil.invalidEx;
import static org.cobbzilla.wizard.server.RestServerBase.reportError;

@Service @Slf4j
public class StandardDeviceIdService implements DeviceIdService {
public class StandardDeviceService implements DeviceService {

public static final File WG_DEVICES_DIR = new File(HOME_DIR, "wg_devices");


+ 4
- 4
bubble-server/src/main/java/bubble/service/stream/StandardAppPrimerService.java View File

@@ -14,7 +14,7 @@ import bubble.model.cloud.BubbleNetwork;
import bubble.model.device.Device;
import bubble.rule.AppRuleDriver;
import bubble.server.BubbleConfiguration;
import bubble.service.cloud.DeviceIdService;
import bubble.service.device.DeviceService;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.cobbzilla.util.collection.SingletonList;
@@ -34,7 +34,7 @@ public class StandardAppPrimerService implements AppPrimerService {

@Autowired private AccountDAO accountDAO;
@Autowired private DeviceDAO deviceDAO;
@Autowired private DeviceIdService deviceIdService;
@Autowired private DeviceService deviceService;
@Autowired private BubbleAppDAO appDAO;
@Autowired private AppMatcherDAO matcherDAO;
@Autowired private AppRuleDAO ruleDAO;
@@ -77,7 +77,7 @@ public class StandardAppPrimerService implements AppPrimerService {
}

public void prime(Account account) {
deviceIdService.initBlockStats(account);
deviceService.initBlockStats(account);
prime(account, (BubbleApp) null);
}

@@ -114,7 +114,7 @@ public class StandardAppPrimerService implements AppPrimerService {
final Map<String, List<String>> accountDeviceIps = new HashMap<>();
final List<Device> devices = deviceDAO.findByAccount(account.getUuid());
for (Device device : devices) {
accountDeviceIps.put(device.getUuid(), deviceIdService.findIpsByDevice(device.getUuid()));
accountDeviceIps.put(device.getUuid(), deviceService.findIpsByDevice(device.getUuid()));
}
if (accountDeviceIps.isEmpty()) return;



bubble-server/src/main/java/bubble/service_dbfilter/DbFilterDeviceIdService.java → bubble-server/src/main/java/bubble/service_dbfilter/DbFilterDeviceService.java View File

@@ -7,7 +7,7 @@ package bubble.service_dbfilter;
import bubble.model.account.Account;
import bubble.model.device.Device;
import bubble.model.device.DeviceStatus;
import bubble.service.cloud.DeviceIdService;
import bubble.service.device.DeviceService;
import org.springframework.stereotype.Service;

import java.util.List;
@@ -15,7 +15,7 @@ import java.util.List;
import static org.cobbzilla.util.daemon.ZillaRuntime.notSupported;

@Service
public class DbFilterDeviceIdService implements DeviceIdService {
public class DbFilterDeviceService implements DeviceService {

@Override public Device findDeviceByIp(String ip) { return notSupported("findDeviceByIp"); }


+ 1
- 1
bubble-server/src/main/resources/messages

@@ -1 +1 @@
Subproject commit 9fcd7bc0a768b124b09b7e8995c27fc94dedf9d8
Subproject commit 2b4074ab37b1e3caa0cb6382352b3391f5bb7139

+ 1
- 1
utils/cobbzilla-wizard

@@ -1 +1 @@
Subproject commit 4dcca7b4ca0240ad7f2cc1d60909c0ff5830339a
Subproject commit 7727825b5e738168a42e4148d873c3f75d572f91

Loading…
Cancel
Save