From 8186a859d91b8340717af3bc8e5bf84a002f33e9 Mon Sep 17 00:00:00 2001 From: Jonathan Cobb Date: Fri, 24 Jul 2020 15:42:44 -0400 Subject: [PATCH] Add GoDaddyCleaner utility. Add copyright headers --- .../dns/godaddy/GoDaddyDnsCleanerMain.java | 145 ++++++++++++++++++ .../dns/godaddy/GoDaddyDnsCleanerOptions.java | 94 ++++++++++++ .../cloud/dns/godaddy/GoDaddyDnsDriver.java | 26 ++-- .../cloud/dns/godaddy/GoDaddyDnsRecord.java | 3 +- .../bubble/dao/account/TrustedClientDAO.java | 4 + .../src/main/java/bubble/main/BubbleMain.java | 4 +- .../bubble/model/account/TrustedClient.java | 4 + .../account/TrustedClientLoginRequest.java | 4 + .../model/account/TrustedClientResponse.java | 4 + .../model/cloud/NodeKeyVerification.java | 4 + .../upgrade/AppsUpgradeNotification.java | 4 + .../account/TrustedAuthResource.java | 4 + .../bubble/rule/BubbleRegexReplacement.java | 4 + .../service/bill/FirstBillNoticeService.java | 42 +++++ .../service/stream/HttpStreamDebug.java | 4 + .../upgrade/AppObjectUpgradeHandler.java | 4 + .../service/upgrade/AppUpgradeService.java | 4 + .../java/db/BubbleValueUpdateMigration.java | 4 + .../main/resources/bubble/host-prefixes.txt | 72 --------- .../packer/roles/nginx/files/init_dhparams.sh | 4 +- bubble-web | 2 +- utils/cobbzilla-utils | 2 +- 22 files changed, 353 insertions(+), 89 deletions(-) create mode 100644 bubble-server/src/main/java/bubble/cloud/dns/godaddy/GoDaddyDnsCleanerMain.java create mode 100644 bubble-server/src/main/java/bubble/cloud/dns/godaddy/GoDaddyDnsCleanerOptions.java create mode 100644 bubble-server/src/main/java/bubble/service/bill/FirstBillNoticeService.java diff --git a/bubble-server/src/main/java/bubble/cloud/dns/godaddy/GoDaddyDnsCleanerMain.java b/bubble-server/src/main/java/bubble/cloud/dns/godaddy/GoDaddyDnsCleanerMain.java new file mode 100644 index 00000000..e12e1a02 --- /dev/null +++ b/bubble-server/src/main/java/bubble/cloud/dns/godaddy/GoDaddyDnsCleanerMain.java @@ -0,0 +1,145 @@ +/** + * Copyright (c) 2020 Bubble, Inc. All rights reserved. + * For personal (non-commercial) use, see license: https://getbubblenow.com/bubble-license/ + */ +package bubble.cloud.dns.godaddy; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ArrayNode; +import lombok.extern.slf4j.Slf4j; +import org.cobbzilla.util.dns.DnsType; +import org.cobbzilla.util.http.HttpRequestBean; +import org.cobbzilla.util.http.HttpResponseBean; +import org.cobbzilla.util.http.HttpUtil; +import org.cobbzilla.util.http.URIUtil; +import org.cobbzilla.util.io.FileUtil; +import org.cobbzilla.util.main.BaseMain; +import org.cobbzilla.util.network.NetworkUtil; + +import java.util.*; +import java.util.stream.Collectors; + +import static bubble.cloud.dns.godaddy.GoDaddyDnsConfig.GODADDY_BASE_URI; +import static org.apache.http.HttpHeaders.CONTENT_TYPE; +import static org.cobbzilla.util.daemon.ZillaRuntime.empty; +import static org.cobbzilla.util.daemon.ZillaRuntime.shortError; +import static org.cobbzilla.util.http.HttpContentTypes.APPLICATION_JSON; +import static org.cobbzilla.util.http.HttpMethods.PUT; +import static org.cobbzilla.util.http.HttpSchemes.SCHEME_HTTP; +import static org.cobbzilla.util.http.HttpUtil.url2string; +import static org.cobbzilla.util.io.FileUtil.abs; +import static org.cobbzilla.util.json.JsonUtil.json; +import static org.cobbzilla.util.network.NetworkUtil.normalizeHost; + +@Slf4j +public class GoDaddyDnsCleanerMain extends BaseMain { + + private static final DnsType[] DNS_TYPES = new DnsType[] { DnsType.A, DnsType.AAAA, DnsType.CNAME }; + + public static void main(String[] args) { main(GoDaddyDnsCleanerMain.class, args); } + + @Override protected void run() throws Exception { + + final GoDaddyDnsCleanerOptions opts = getOptions(); + + Set bubbleHosts; + try { + bubbleHosts = new HashSet<>(FileUtil.toStringList(opts.getBubbleHostsFile())); + } catch (Exception e) { + err("Error reading bubbleHosts file: "+shortError(e)); + return; + } + if (empty(bubbleHosts)) { + err("No bubble hosts found in file: "+abs(opts.getBubbleHostsFile())); + return; + } + if (bubbleHosts.iterator().next().contains(",")) { + bubbleHosts = bubbleHosts.stream() + .map(h -> h.split(",")[2]) + .map(NetworkUtil::normalizeHost) + .collect(Collectors.toSet()); + } + + final String bootUrl = opts.getBootUrl(); + final HttpResponseBean bootJsonResponse = HttpUtil.getResponse(bootUrl); + if (!bootJsonResponse.isOk()) { + err("Error loading boot.json from "+bootUrl+": "+bootJsonResponse); + } + + Set sageSet = new TreeSet<>(); + try { + final JsonNode bootJson = json(bootJsonResponse.getEntityString(), JsonNode.class); + final ArrayNode sages = (ArrayNode) bootJson.get("sages"); + for (int i=0; i retain = new TreeSet<>(); + retain.addAll(bubbleHosts); + retain.addAll(bubbleHosts.stream() + .map(h -> { + final int firstDot = h.indexOf('.'); + if (firstDot == -1 || firstDot == h.length()-1) throw new IllegalStateException("invalid bubble host: "+h); + return h.substring(firstDot+1); + }) + .collect(Collectors.toSet())); + retain.addAll(sageSet); + retain.addAll(opts.getAdditionalSages()); + retain.addAll(opts.getRetainHosts()); + + final GoDaddyDnsDriver dns = new GoDaddyDnsDriver(); + dns.setCredentials(opts.getCredentials()); + + final Set bubbleDomains = bubbleHosts.stream().map(URIUtil::hostToDomain).collect(Collectors.toSet()); + for (String domain : bubbleDomains) { + final String url = GODADDY_BASE_URI + domain + "/records"; + try { + for (DnsType type : DNS_TYPES) { + final Set removed = new HashSet<>(); + final Set retainRecords = new HashSet<>(); + final GoDaddyDnsRecord[] dnsRecords = dns._listGoDaddyDnsRecords(url+"/"+type); + for (GoDaddyDnsRecord rec : dnsRecords) { + final String host = rec.getName() + "." + domain; + if (retain.contains(host)) { + retainRecords.add(rec); + } else { + if (opts.hasHttpCheckTimeout()) { + try { + url2string(SCHEME_HTTP + host + "/", opts.getHttpCheckTimeoutMillis()); + final String msg = "Host seems alive, not removing: " + host; + log.warn(msg); + out("WARN: " + msg); + retainRecords.add(rec); + } catch (Exception e) { + final String message = "Error connecting to " + host + ": " + shortError(e); + log.debug(message); + out(message); + removed.add(rec); + } + } else { + removed.add(rec); + } + } + } + + log.info("Removing "+type+" records:\n" + json(removed)); + final HttpRequestBean domainUpdate = dns.auth(url+"/"+type) + .setMethod(PUT) + .setHeader(CONTENT_TYPE, APPLICATION_JSON) + .setEntity(json(retainRecords)); + final HttpResponseBean response = HttpUtil.getResponse(domainUpdate); + if (!response.isOk()) { + log.error("Error updating "+type+" records for domain: " + domain + ": " + response); + } + } + } catch (Exception e) { + log.error("Error reading DNS records for domain: "+domain+": "+shortError(e)); + } + } + } + +} diff --git a/bubble-server/src/main/java/bubble/cloud/dns/godaddy/GoDaddyDnsCleanerOptions.java b/bubble-server/src/main/java/bubble/cloud/dns/godaddy/GoDaddyDnsCleanerOptions.java new file mode 100644 index 00000000..664d9444 --- /dev/null +++ b/bubble-server/src/main/java/bubble/cloud/dns/godaddy/GoDaddyDnsCleanerOptions.java @@ -0,0 +1,94 @@ +/** + * Copyright (c) 2020 Bubble, Inc. All rights reserved. + * For personal (non-commercial) use, see license: https://getbubblenow.com/bubble-license/ + */ +package bubble.cloud.dns.godaddy; + +import bubble.model.cloud.CloudCredentials; +import lombok.Getter; +import lombok.Setter; +import org.cobbzilla.util.collection.NameAndValue; +import org.cobbzilla.util.main.BaseMainOptions; +import org.kohsuke.args4j.Option; + +import java.io.File; +import java.io.IOException; +import java.util.Collections; +import java.util.Set; + +import static java.util.concurrent.TimeUnit.SECONDS; +import static org.cobbzilla.util.daemon.ZillaRuntime.empty; +import static org.cobbzilla.util.network.NetworkUtil.toHostSet; + +public class GoDaddyDnsCleanerOptions extends BaseMainOptions { + + public static final String VAR_GODADDY_API_KEY = "GODADDY_API_KEY"; + public static final String VAR_GODADDY_API_SECRET = "GODADDY_API_SECRET"; + public static final String DEFAULT_BOOT_URL = "https://raw.githubusercontent.com/getbubblenow/bubble-config/master/boot.json"; + + public static final String USAGE_API_KEY_ENV_VAR = "Name of environment variable containing GoDaddy API Key. Default is "+VAR_GODADDY_API_KEY; + public static final String OPT_API_KEY_ENV_VAR = "-k"; + public static final String LONGOPT_API_KEY_ENV_VAR = "--api-key"; + public static final int DEFAULT_HTTP_CHECK_TIMEOUT_SECONDS = 10; + @Option(name=OPT_API_KEY_ENV_VAR, aliases=LONGOPT_API_KEY_ENV_VAR, usage=USAGE_API_KEY_ENV_VAR) + @Getter @Setter private String apiKeyVar = VAR_GODADDY_API_KEY; + + public static final String USAGE_SECRET_KEY_ENV_VAR = "Name of environment variable containing GoDaddy Secret Key. Default is "+VAR_GODADDY_API_SECRET; + public static final String OPT_SECRET_KEY_ENV_VAR = "-s"; + public static final String LONGOPT_SECRET_KEY_ENV_VAR = "--secret-key"; + @Option(name=OPT_SECRET_KEY_ENV_VAR, aliases=LONGOPT_SECRET_KEY_ENV_VAR, usage=USAGE_SECRET_KEY_ENV_VAR) + @Getter @Setter private String secretKeyVar = VAR_GODADDY_API_SECRET; + + public static final String USAGE_LIVE_BUBBLES = "File containing live/running Bubbles, one hostname per line. DNS records for these will be retained"; + public static final String OPT_LIVE_BUBBLES = "-b"; + public static final String LONGOPT_LIVE_BUBBLES = "--bubbles-file"; + @Option(name=OPT_LIVE_BUBBLES, aliases=LONGOPT_LIVE_BUBBLES, usage=USAGE_LIVE_BUBBLES, required=true) + @Getter @Setter private File bubbleHostsFile; + + public static final String USAGE_BOOT_CONFIG_URL = "Url or File to boot.json containing initial sages. Default is "+DEFAULT_BOOT_URL; + public static final String OPT_BOOT_CONFIG_URL = "-B"; + public static final String LONGOPT_BOOT_CONFIG_URL = "--boot"; + @Option(name=OPT_BOOT_CONFIG_URL, aliases=LONGOPT_BOOT_CONFIG_URL, usage=USAGE_BOOT_CONFIG_URL) + @Getter @Setter private String bootUrl = DEFAULT_BOOT_URL; + + public static final String USAGE_ADDITIONAL_SAGES = "File containing additional sage hosts, one per line"; + public static final String OPT_ADDITIONAL_SAGES = "-A"; + public static final String LONGOPT_ADDITIONAL_SAGES = "--additional-sages"; + @Option(name=OPT_ADDITIONAL_SAGES, aliases=LONGOPT_ADDITIONAL_SAGES, usage=USAGE_ADDITIONAL_SAGES) + @Getter @Setter private File additionalSagesFile; + public boolean hasAdditionalSagesFile () { return !empty(additionalSagesFile); } + public Set getAdditionalSages () throws IOException { + return hasAdditionalSagesFile() ? toHostSet(additionalSagesFile) : Collections.emptySet(); + } + + public static final String USAGE_RETAIN_HOSTS = "File containing additional hosts to retain, one per line"; + public static final String OPT_RETAIN_HOSTS = "-R"; + public static final String LONGOPT_RETAIN_HOSTS = "--retain-hosts"; + @Option(name=OPT_RETAIN_HOSTS, aliases=LONGOPT_RETAIN_HOSTS, usage=USAGE_RETAIN_HOSTS) + @Getter @Setter private File retainHostsFile; + public boolean hasRetainHostsFile () { return !empty(retainHostsFile); } + public Set getRetainHosts () throws IOException { + return hasRetainHostsFile() ? toHostSet(retainHostsFile) : Collections.emptySet(); + } + + public static final String USAGE_HTTP_CHECK = "Timeout for HTTP check in seconds. Use zero to disable check. Default is "+DEFAULT_HTTP_CHECK_TIMEOUT_SECONDS+" seconds"; + public static final String OPT_HTTP_CHECK = "-H"; + public static final String LONGOPT_HTTP_CHECK = "--http-check-timeout"; + @Option(name=OPT_HTTP_CHECK, aliases=LONGOPT_HTTP_CHECK, usage=USAGE_HTTP_CHECK) + @Getter @Setter private long httpCheckTimeout = DEFAULT_HTTP_CHECK_TIMEOUT_SECONDS; + public boolean hasHttpCheckTimeout () { return getHttpCheckTimeout() > 0; } + public long getHttpCheckTimeoutMillis () { return SECONDS.toMillis(getHttpCheckTimeout()); } + + public CloudCredentials getCredentials() { + final String apiKey = System.getenv(getApiKeyVar()); + if (empty(apiKey)) throw new IllegalArgumentException("Env var not found or empty: "+getApiKeyVar()); + + final String secretKey = System.getenv(getSecretKeyVar()); + if (empty(secretKey)) throw new IllegalArgumentException("Env var not found or empty: "+getApiKeyVar()); + + return new CloudCredentials(new NameAndValue[] { + new NameAndValue(VAR_GODADDY_API_KEY, apiKey), + new NameAndValue(VAR_GODADDY_API_SECRET, secretKey), + }); + } +} diff --git a/bubble-server/src/main/java/bubble/cloud/dns/godaddy/GoDaddyDnsDriver.java b/bubble-server/src/main/java/bubble/cloud/dns/godaddy/GoDaddyDnsDriver.java index e1211ee6..a9e7b224 100644 --- a/bubble-server/src/main/java/bubble/cloud/dns/godaddy/GoDaddyDnsDriver.java +++ b/bubble-server/src/main/java/bubble/cloud/dns/godaddy/GoDaddyDnsDriver.java @@ -195,18 +195,20 @@ public class GoDaddyDnsDriver extends DnsDriverBase { private final Map listCache = new ExpirationMap<>(SECONDS.toMillis(10)); public GoDaddyDnsRecord[] listGoDaddyDnsRecords(final String goDaddyApiUrl) { - return listCache.computeIfAbsent(goDaddyApiUrl, url -> { - final var request = auth(url); - final HttpResponseBean response; - try { - response = HttpUtil.getResponse(request); - } catch (Exception e) { - log.error("listGoDaddyDnsRecords(" + url + "): " + e, e); - return GoDaddyDnsRecord.EMPTY_ARRAY; - } - if (!response.isOk()) throw new IllegalStateException("listGoDaddyDnsRecords: " + response); - return json(response.getEntityString(), GoDaddyDnsRecord[].class); - }); + return listCache.computeIfAbsent(goDaddyApiUrl, this::_listGoDaddyDnsRecords); + } + + public GoDaddyDnsRecord[] _listGoDaddyDnsRecords(String url) { + final var request = auth(url); + final HttpResponseBean response; + try { + response = HttpUtil.getResponse(request); + } catch (Exception e) { + log.error("listGoDaddyDnsRecords(" + url + "): " + e, e); + return GoDaddyDnsRecord.EMPTY_ARRAY; + } + if (!response.isOk()) throw new IllegalStateException("listGoDaddyDnsRecords: " + response); + return json(response.getEntityString(), GoDaddyDnsRecord[].class); } public HttpRequestBean auth(String url) { return new HttpRequestBean(url).setHeader(AUTHORIZATION, getAuthValue()); } diff --git a/bubble-server/src/main/java/bubble/cloud/dns/godaddy/GoDaddyDnsRecord.java b/bubble-server/src/main/java/bubble/cloud/dns/godaddy/GoDaddyDnsRecord.java index f9b63c10..1034cfb2 100644 --- a/bubble-server/src/main/java/bubble/cloud/dns/godaddy/GoDaddyDnsRecord.java +++ b/bubble-server/src/main/java/bubble/cloud/dns/godaddy/GoDaddyDnsRecord.java @@ -5,6 +5,7 @@ package bubble.cloud.dns.godaddy; import bubble.model.cloud.BubbleDomain; +import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @@ -14,7 +15,7 @@ import org.cobbzilla.util.dns.DnsType; import static org.cobbzilla.util.dns.DnsRecord.OPT_NS_NAME; -@NoArgsConstructor @Accessors(chain=true) +@NoArgsConstructor @Accessors(chain=true) @EqualsAndHashCode(of={"name", "type", "data"}) public class GoDaddyDnsRecord { public static final GoDaddyDnsRecord[] EMPTY_ARRAY = new GoDaddyDnsRecord[0]; diff --git a/bubble-server/src/main/java/bubble/dao/account/TrustedClientDAO.java b/bubble-server/src/main/java/bubble/dao/account/TrustedClientDAO.java index ff024f7a..d5952988 100644 --- a/bubble-server/src/main/java/bubble/dao/account/TrustedClientDAO.java +++ b/bubble-server/src/main/java/bubble/dao/account/TrustedClientDAO.java @@ -1,3 +1,7 @@ +/** + * Copyright (c) 2020 Bubble, Inc. All rights reserved. + * For personal (non-commercial) use, see license: https://getbubblenow.com/bubble-license/ + */ package bubble.dao.account; import bubble.model.account.TrustedClient; diff --git a/bubble-server/src/main/java/bubble/main/BubbleMain.java b/bubble-server/src/main/java/bubble/main/BubbleMain.java index 6da67751..851b3521 100644 --- a/bubble-server/src/main/java/bubble/main/BubbleMain.java +++ b/bubble-server/src/main/java/bubble/main/BubbleMain.java @@ -4,6 +4,7 @@ */ package bubble.main; +import bubble.cloud.dns.godaddy.GoDaddyDnsCleanerMain; import bubble.main.http.BubbleHttpDeleteMain; import bubble.main.http.BubbleHttpGetMain; import bubble.main.http.BubbleHttpPostMain; @@ -36,7 +37,8 @@ public class BubbleMain { {"rekey", RekeyDatabaseMain.class}, {"generate-algo-conf", GenerateAlgoConfMain.class}, {"const", ConstMain.class}, - {"file-header", FileHeaderMain.class} + {"file-header", FileHeaderMain.class}, + {"gd-cleanup", GoDaddyDnsCleanerMain.class} }); public static void main(String[] args) throws Exception { diff --git a/bubble-server/src/main/java/bubble/model/account/TrustedClient.java b/bubble-server/src/main/java/bubble/model/account/TrustedClient.java index 62d6183c..3a72f756 100644 --- a/bubble-server/src/main/java/bubble/model/account/TrustedClient.java +++ b/bubble-server/src/main/java/bubble/model/account/TrustedClient.java @@ -1,3 +1,7 @@ +/** + * Copyright (c) 2020 Bubble, Inc. All rights reserved. + * For personal (non-commercial) use, see license: https://getbubblenow.com/bubble-license/ + */ package bubble.model.account; diff --git a/bubble-server/src/main/java/bubble/model/account/TrustedClientLoginRequest.java b/bubble-server/src/main/java/bubble/model/account/TrustedClientLoginRequest.java index 391028d5..4f84e4eb 100644 --- a/bubble-server/src/main/java/bubble/model/account/TrustedClientLoginRequest.java +++ b/bubble-server/src/main/java/bubble/model/account/TrustedClientLoginRequest.java @@ -1,3 +1,7 @@ +/** + * Copyright (c) 2020 Bubble, Inc. All rights reserved. + * For personal (non-commercial) use, see license: https://getbubblenow.com/bubble-license/ + */ package bubble.model.account; import com.fasterxml.jackson.annotation.JsonIgnore; diff --git a/bubble-server/src/main/java/bubble/model/account/TrustedClientResponse.java b/bubble-server/src/main/java/bubble/model/account/TrustedClientResponse.java index 8a2ae6d8..a98ebf82 100644 --- a/bubble-server/src/main/java/bubble/model/account/TrustedClientResponse.java +++ b/bubble-server/src/main/java/bubble/model/account/TrustedClientResponse.java @@ -1,3 +1,7 @@ +/** + * Copyright (c) 2020 Bubble, Inc. All rights reserved. + * For personal (non-commercial) use, see license: https://getbubblenow.com/bubble-license/ + */ package bubble.model.account; import lombok.AllArgsConstructor; diff --git a/bubble-server/src/main/java/bubble/model/cloud/NodeKeyVerification.java b/bubble-server/src/main/java/bubble/model/cloud/NodeKeyVerification.java index 1a289691..c8252449 100644 --- a/bubble-server/src/main/java/bubble/model/cloud/NodeKeyVerification.java +++ b/bubble-server/src/main/java/bubble/model/cloud/NodeKeyVerification.java @@ -1,3 +1,7 @@ +/** + * Copyright (c) 2020 Bubble, Inc. All rights reserved. + * For personal (non-commercial) use, see license: https://getbubblenow.com/bubble-license/ + */ package bubble.model.cloud; import lombok.Getter; diff --git a/bubble-server/src/main/java/bubble/notify/upgrade/AppsUpgradeNotification.java b/bubble-server/src/main/java/bubble/notify/upgrade/AppsUpgradeNotification.java index ab8e12d0..38bd97eb 100644 --- a/bubble-server/src/main/java/bubble/notify/upgrade/AppsUpgradeNotification.java +++ b/bubble-server/src/main/java/bubble/notify/upgrade/AppsUpgradeNotification.java @@ -1,3 +1,7 @@ +/** + * Copyright (c) 2020 Bubble, Inc. All rights reserved. + * For personal (non-commercial) use, see license: https://getbubblenow.com/bubble-license/ + */ package bubble.notify.upgrade; import bubble.model.app.AppTemplateEntity; diff --git a/bubble-server/src/main/java/bubble/resources/account/TrustedAuthResource.java b/bubble-server/src/main/java/bubble/resources/account/TrustedAuthResource.java index 30f18cce..6c812126 100644 --- a/bubble-server/src/main/java/bubble/resources/account/TrustedAuthResource.java +++ b/bubble-server/src/main/java/bubble/resources/account/TrustedAuthResource.java @@ -1,3 +1,7 @@ +/** + * Copyright (c) 2020 Bubble, Inc. All rights reserved. + * For personal (non-commercial) use, see license: https://getbubblenow.com/bubble-license/ + */ package bubble.resources.account; import bubble.dao.SessionDAO; diff --git a/bubble-server/src/main/java/bubble/rule/BubbleRegexReplacement.java b/bubble-server/src/main/java/bubble/rule/BubbleRegexReplacement.java index 75dfb739..29a47f47 100644 --- a/bubble-server/src/main/java/bubble/rule/BubbleRegexReplacement.java +++ b/bubble-server/src/main/java/bubble/rule/BubbleRegexReplacement.java @@ -1,3 +1,7 @@ +/** + * Copyright (c) 2020 Bubble, Inc. All rights reserved. + * For personal (non-commercial) use, see license: https://getbubblenow.com/bubble-license/ + */ package bubble.rule; import lombok.Getter; diff --git a/bubble-server/src/main/java/bubble/service/bill/FirstBillNoticeService.java b/bubble-server/src/main/java/bubble/service/bill/FirstBillNoticeService.java new file mode 100644 index 00000000..604949a3 --- /dev/null +++ b/bubble-server/src/main/java/bubble/service/bill/FirstBillNoticeService.java @@ -0,0 +1,42 @@ +/** + * Copyright (c) 2020 Bubble, Inc. All rights reserved. + * For personal (non-commercial) use, see license: https://getbubblenow.com/bubble-license/ + */ +package bubble.service.bill; + +import bubble.dao.bill.AccountPlanDAO; +import bubble.dao.bill.BillDAO; +import bubble.dao.bill.BubblePlanDAO; +import bubble.model.bill.AccountPlan; +import lombok.extern.slf4j.Slf4j; +import org.cobbzilla.util.daemon.SimpleDaemon; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +import static java.util.concurrent.TimeUnit.DAYS; +import static java.util.concurrent.TimeUnit.HOURS; +import static org.cobbzilla.util.daemon.ZillaRuntime.now; + +@Service @Slf4j +public class FirstBillNoticeService extends SimpleDaemon { + + private static final long BILLING_CHECK_INTERVAL = HOURS.toMillis(6); + @Override protected long getSleepTime() { return BILLING_CHECK_INTERVAL; } + + @Autowired private AccountPlanDAO accountPlanDAO; + @Autowired private BubblePlanDAO planDAO; + @Autowired private BillDAO billDAO; + + @Override protected void process() { + + // sort plans by Account ctime, newer Accounts are billed before older Accounts + final List plansToBillSoon = accountPlanDAO.findBillableAccountPlans(now()+DAYS.toMillis(3)); + + // iterate plans, find plans that have no promotions to apply and will thus actually be charged + // for each such plan, send an email to the account owner telling them: + // when they will be billed, what the amount will be, how it will appear on their statement, and how to cancel + + } +} diff --git a/bubble-server/src/main/java/bubble/service/stream/HttpStreamDebug.java b/bubble-server/src/main/java/bubble/service/stream/HttpStreamDebug.java index 06565308..75ba525d 100644 --- a/bubble-server/src/main/java/bubble/service/stream/HttpStreamDebug.java +++ b/bubble-server/src/main/java/bubble/service/stream/HttpStreamDebug.java @@ -1,3 +1,7 @@ +/** + * Copyright (c) 2020 Bubble, Inc. All rights reserved. + * For personal (non-commercial) use, see license: https://getbubblenow.com/bubble-license/ + */ package bubble.service.stream; import lombok.extern.slf4j.Slf4j; diff --git a/bubble-server/src/main/java/bubble/service/upgrade/AppObjectUpgradeHandler.java b/bubble-server/src/main/java/bubble/service/upgrade/AppObjectUpgradeHandler.java index a08f3ef8..9e0bece4 100644 --- a/bubble-server/src/main/java/bubble/service/upgrade/AppObjectUpgradeHandler.java +++ b/bubble-server/src/main/java/bubble/service/upgrade/AppObjectUpgradeHandler.java @@ -1,3 +1,7 @@ +/** + * Copyright (c) 2020 Bubble, Inc. All rights reserved. + * For personal (non-commercial) use, see license: https://getbubblenow.com/bubble-license/ + */ package bubble.service.upgrade; import bubble.dao.app.AppTemplateEntityDAO; diff --git a/bubble-server/src/main/java/bubble/service/upgrade/AppUpgradeService.java b/bubble-server/src/main/java/bubble/service/upgrade/AppUpgradeService.java index b4f14420..17762389 100644 --- a/bubble-server/src/main/java/bubble/service/upgrade/AppUpgradeService.java +++ b/bubble-server/src/main/java/bubble/service/upgrade/AppUpgradeService.java @@ -1,3 +1,7 @@ +/** + * Copyright (c) 2020 Bubble, Inc. All rights reserved. + * For personal (non-commercial) use, see license: https://getbubblenow.com/bubble-license/ + */ package bubble.service.upgrade; import bubble.dao.account.AccountDAO; diff --git a/bubble-server/src/main/java/db/BubbleValueUpdateMigration.java b/bubble-server/src/main/java/db/BubbleValueUpdateMigration.java index e87e0c62..72f92a3e 100644 --- a/bubble-server/src/main/java/db/BubbleValueUpdateMigration.java +++ b/bubble-server/src/main/java/db/BubbleValueUpdateMigration.java @@ -1,3 +1,7 @@ +/** + * Copyright (c) 2020 Bubble, Inc. All rights reserved. + * For personal (non-commercial) use, see license: https://getbubblenow.com/bubble-license/ + */ package db; import lombok.NonNull; diff --git a/bubble-server/src/main/resources/bubble/host-prefixes.txt b/bubble-server/src/main/resources/bubble/host-prefixes.txt index e2565d96..375196cd 100644 --- a/bubble-server/src/main/resources/bubble/host-prefixes.txt +++ b/bubble-server/src/main/resources/bubble/host-prefixes.txt @@ -2561,7 +2561,6 @@ dearn dears deary deash -death deave deaws deawy @@ -2570,10 +2569,6 @@ debar debby debel debes -debit -debts -debud -debug debur debus debut @@ -2600,7 +2595,6 @@ deers deets deeve deevs -defat defer deffo defis @@ -2636,9 +2630,6 @@ deman demes demic demit -demob -demon -demos dempt demur denar @@ -2664,13 +2655,11 @@ derns deros derro derry -derth dervs deshi desks desse deter -detox deuce devas devel @@ -2679,7 +2668,6 @@ devon devot dewan dewar -dewax dewed dexes dexie @@ -2730,19 +2718,16 @@ dined diner dines dinge -dingo dings dingy dinic dinks -dinky dinna dinos dints diode diols diota -dippy dipso diram direr @@ -2751,7 +2736,6 @@ dirke dirks dirls dirts -dirty disas disci disco @@ -2768,7 +2752,6 @@ ditsy ditto ditts ditty -ditzy divan divas dived @@ -2838,7 +2821,6 @@ donas donee doner donga -dongs donko donna donne @@ -2939,7 +2921,6 @@ drays dread dream drear -dreck dreed drees dregs @@ -2982,7 +2963,6 @@ drove drown drows drubs -drugs druid drums drunk @@ -3073,7 +3053,6 @@ dwams dwang dwarf dwaum -dweeb dwell dwelt dwile @@ -3129,7 +3108,6 @@ edile edits educe educt -eejit eerie eeven eevns @@ -3221,8 +3199,6 @@ ender endew endow endue -enema -enemy enews enfix eniac @@ -3389,9 +3365,7 @@ fados faena faery faffs -faggy fagin -fagot faiks fails faine @@ -3400,11 +3374,6 @@ faint fairs fairy faith -faked -faker -fakes -fakey -fakie fakir falaj falls @@ -3436,18 +3405,9 @@ farle farls farms faros -farse -farts fasci fasti fasts -fatal -fated -fates -fatly -fatso -fatty -fatwa faugh fauld fault @@ -3500,13 +3460,9 @@ felid fella fells felly -felon felts felty femal -femes -femme -femmy femur fence fends @@ -3539,9 +3495,7 @@ fetid fetor fetta fetts -fetwa feuar -feuds feued fever fewer @@ -3646,7 +3600,6 @@ flail flair flake flaks -flaky flame flamm flams @@ -3673,7 +3626,6 @@ flees fleet flegs fleme -flesh flews flexo fleys @@ -3698,7 +3650,6 @@ flobs flock flocs floes -flogs flong flood floor @@ -3720,8 +3671,6 @@ flues fluey fluff fluid -fluke -fluky flume flump flung @@ -3831,7 +3780,6 @@ frats fraud fraus frays -freak freed freer frees @@ -11742,7 +11690,6 @@ warty wases washy wasps -waspy waste wasts watap @@ -11815,7 +11762,6 @@ welly welsh welts wembs -wench wends wenge wenny @@ -11862,9 +11808,6 @@ whigs while whilk whims -whine -whins -whiny whios whips whipt @@ -11936,7 +11879,6 @@ wingy winks winna winns -winos winze wiped wiper @@ -11961,9 +11903,6 @@ withe withs withy witty -wived -wiver -wives wizen wizes woads @@ -11981,16 +11920,12 @@ wonks wonky wonts woods -woody -wooed -wooer woofs woofy woold wools wooly woons -woops woose woosh wootz @@ -12054,7 +11989,6 @@ xenia xenic xenon xeric -xerox xerus xoana xrays @@ -12183,16 +12117,12 @@ yogis yoick yojan yoked -yokel yoker yokes -yokul yolks yolky yomim yomps -yonic -yonis yonks yoofs yoops @@ -12232,7 +12162,6 @@ yummo yummy yumps yupon -yuppy yurta yurts yuzus @@ -12272,7 +12201,6 @@ zibet ziffs zigan zilas -zilch zilla zills zimbi diff --git a/bubble-server/src/main/resources/packer/roles/nginx/files/init_dhparams.sh b/bubble-server/src/main/resources/packer/roles/nginx/files/init_dhparams.sh index a4dba2b9..270a1e50 100644 --- a/bubble-server/src/main/resources/packer/roles/nginx/files/init_dhparams.sh +++ b/bubble-server/src/main/resources/packer/roles/nginx/files/init_dhparams.sh @@ -1,5 +1,7 @@ #!/bin/bash - +# +# Copyright (c) 2020 Bubble, Inc. All rights reserved. For personal (non-commercial) use, see license: https://getbubblenow.com/bubble-license/ +# LOG=/tmp/dhparams.log DH_PARAMS=/etc/nginx/dhparams.pem diff --git a/bubble-web b/bubble-web index 55cc17c6..7974c29c 160000 --- a/bubble-web +++ b/bubble-web @@ -1 +1 @@ -Subproject commit 55cc17c6c4241b8eb6c1ada2ce29ce08307bbfee +Subproject commit 7974c29cd2cf5eb312ae98de6f7a884258812268 diff --git a/utils/cobbzilla-utils b/utils/cobbzilla-utils index fc871562..622fcee1 160000 --- a/utils/cobbzilla-utils +++ b/utils/cobbzilla-utils @@ -1 +1 @@ -Subproject commit fc87156268ff3380321b83d9b6e2408441f58047 +Subproject commit 622fcee16099536b72aefc92475463a1e9b28756