浏览代码

reserve account names as network names, better name validation for new networks

tags/v0.9.14
Jonathan Cobb 4 年前
父节点
当前提交
7cb663cc1c
共有 7 个文件被更改,包括 55 次插入28 次删除
  1. +7
    -1
      bubble-server/src/main/java/bubble/dao/cloud/BubbleNetworkDAO.java
  2. +4
    -2
      bubble-server/src/main/java/bubble/model/account/Account.java
  3. +2
    -2
      bubble-server/src/main/java/bubble/model/bill/AccountPlan.java
  4. +28
    -10
      bubble-server/src/main/java/bubble/model/cloud/BubbleNetwork.java
  5. +2
    -2
      bubble-server/src/main/java/bubble/resources/bill/AccountPlansResource.java
  6. +0
    -11
      bubble-server/src/main/resources/message_templates/en_US/server/post_auth/ResourceMessages.properties
  7. +12
    -0
      bubble-server/src/main/resources/message_templates/en_US/server/pre_auth/ResourceMessages.properties

+ 7
- 1
bubble-server/src/main/java/bubble/dao/cloud/BubbleNetworkDAO.java 查看文件

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

import bubble.dao.account.AccountDAO;
import bubble.dao.account.AccountOwnedEntityDAO;
import bubble.dao.bill.AccountPlanDAO;
import bubble.model.bill.AccountPlan;
@@ -29,6 +30,7 @@ import static org.cobbzilla.wizard.resources.ResourceUtil.invalidEx;
@Repository @Slf4j
public class BubbleNetworkDAO extends AccountOwnedEntityDAO<BubbleNetwork> {

@Autowired private AccountDAO accountDAO;
@Autowired private BubbleDomainDAO domainDAO;
@Autowired private NetworkService networkService;
@Autowired private BubbleBackupDAO backupDAO;
@@ -40,7 +42,7 @@ public class BubbleNetworkDAO extends AccountOwnedEntityDAO<BubbleNetwork> {

@Override public Object preCreate(BubbleNetwork network) {
if (!network.hasForkHost()) {
final ValidationResult errors = validateHostname(network);
final ValidationResult errors = validateHostname(network, accountDAO, this);
if (errors.isInvalid()) throw invalidEx(errors);
}
final AnsibleInstallType installType = network.hasForkHost() && configuration.isSageLauncher()
@@ -85,6 +87,10 @@ public class BubbleNetworkDAO extends AccountOwnedEntityDAO<BubbleNetwork> {
return findByUniqueFields("name", name, "domainName", domainName);
}

public BubbleNetwork findByNameAndDomainUuid(String name, String domainUuid) {
return findByUniqueFields("name", name, "domain", domainUuid);
}

@Override public void delete(String uuid) { delete(uuid, false); }
@Override public void forceDelete(String uuid) { delete(uuid, true); }



+ 4
- 2
bubble-server/src/main/java/bubble/model/account/Account.java 查看文件

@@ -116,9 +116,11 @@ public class Account extends IdentifiableBaseParentEntity implements TokenPrinci

private static final List<String> RESERVED_NAMES = Arrays.asList(
"root", "postmaster", "hostmaster", "webmaster",
"ftp", "www", "www-data", "postgres", "ipfs",
"dns", "dnscrypt", "dnscrypt-proxy", "ftp", "www", "www-data", "postgres", "ipfs",
"redis", "nginx", "mitmproxy", "mitmdump", "algo", "algovpn");
public boolean hasReservedName () { return hasName() && RESERVED_NAMES.contains(getName()); }
public boolean hasReservedName () { return hasName() && isReservedName(getName()); }

public static boolean isReservedName(String name) { return RESERVED_NAMES.contains(name); }

// make this updatable if we ever want accounts to be able to change parents
// there might be a lot more involved in that action though (read-only parent objects that will no longer be visible, must be copied in?)


+ 2
- 2
bubble-server/src/main/java/bubble/model/bill/AccountPlan.java 查看文件

@@ -6,7 +6,7 @@ package bubble.model.bill;

import bubble.model.account.Account;
import bubble.model.account.AccountSshKey;
import bubble.model.account.HasAccount;
import bubble.model.account.HasNetwork;
import bubble.model.cloud.BubbleDomain;
import bubble.model.cloud.BubbleNetwork;
import bubble.model.cloud.CloudService;
@@ -40,7 +40,7 @@ import static org.cobbzilla.util.reflect.ReflectionUtil.copy;
@ECIndex(unique=true, of={"account", "network"}),
@ECIndex(unique=true, of={"plan", "network"})
})
public class AccountPlan extends IdentifiableBase implements HasAccount {
public class AccountPlan extends IdentifiableBase implements HasNetwork {

public static final String[] UPDATE_FIELDS = {"description", "paymentMethod", "paymentMethodObject"};



+ 28
- 10
bubble-server/src/main/java/bubble/model/cloud/BubbleNetwork.java 查看文件

@@ -5,6 +5,8 @@
package bubble.model.cloud;

import bubble.cloud.compute.ComputeNodeSizeType;
import bubble.dao.account.AccountDAO;
import bubble.dao.cloud.BubbleNetworkDAO;
import bubble.model.BubbleTags;
import bubble.model.HasBubbleTags;
import bubble.model.account.Account;
@@ -20,7 +22,6 @@ import lombok.experimental.Accessors;
import org.cobbzilla.util.collection.ArrayUtil;
import org.cobbzilla.wizard.model.Identifiable;
import org.cobbzilla.wizard.model.IdentifiableBase;
import org.cobbzilla.wizard.model.NamedEntity;
import org.cobbzilla.wizard.model.entityconfig.EntityFieldType;
import org.cobbzilla.wizard.model.entityconfig.annotations.*;
import org.cobbzilla.wizard.validation.HasValue;
@@ -179,19 +180,36 @@ public class BubbleNetwork extends IdentifiableBase implements HasNetwork, HasBu
return die("hostFromFqdn("+fqdn+"): expected suffix ."+getNetworkDomain());
}

public static ValidationResult validateHostname(NamedEntity request) {
return validateHostname(request, new ValidationResult());
public static ValidationResult validateHostname(HasNetwork request,
AccountDAO accountDAO,
BubbleNetworkDAO networkDAO) {
return validateHostname(request, new ValidationResult(), accountDAO, networkDAO);
}

public static ValidationResult validateHostname(NamedEntity request, ValidationResult errors) {
public static ValidationResult validateHostname(HasNetwork request,
ValidationResult errors,
AccountDAO accountDAO,
BubbleNetworkDAO networkDAO) {
if (!request.hasName()) {
errors.addViolation("err.name.required");
} else if (!validateRegexMatches(HOST_PART_PATTERN, request.getName())) {
errors.addViolation("err.name.invalid");
} else if (request.getName().length() > NETWORK_NAME_MAXLEN) {
errors.addViolation("err.name.length");
} else if (request.getName().length() < NETWORK_NAME_MINLEN) {
errors.addViolation("err.name.tooShort");
} else {
final String name = request.getName();
if (!validateRegexMatches(HOST_PART_PATTERN, name)) {
errors.addViolation("err.name.invalid");
} else if (Account.isReservedName(name)) {
errors.addViolation("err.name.reserved");
} else if (name.length() > NETWORK_NAME_MAXLEN) {
errors.addViolation("err.name.length");
} else if (name.length() < NETWORK_NAME_MINLEN) {
errors.addViolation("err.name.tooShort");
} else if (networkDAO.findByNameAndDomainUuid(name, request.getDomain()) != null) {
errors.addViolation("err.name.alreadyInUse");
} else {
final Account acct = accountDAO.findByName(name);
if (acct != null && !acct.getUuid().equals(request.getAccount())) {
errors.addViolation("err.name.reservedForAccount");
}
}
}
return errors;
}


+ 2
- 2
bubble-server/src/main/java/bubble/resources/bill/AccountPlansResource.java 查看文件

@@ -146,11 +146,11 @@ public class AccountPlansResource extends AccountOwnedResource<AccountPlan, Acco
errors.addViolation("err.forkHost.domainMismatch");
} else if (domain != null) {
request.setName(domain.networkFromFqdn(forkHost, errors));
validateHostname(request, errors);
validateHostname(request, errors, accountDAO, networkDAO);
}
}
} else {
validateHostname(request, errors);
validateHostname(request, errors, accountDAO, networkDAO);
}

final BubblePlan plan = planDAO.findByAccountOrParentAndId(caller, request.getPlan());


+ 0
- 11
bubble-server/src/main/resources/message_templates/en_US/server/post_auth/ResourceMessages.properties 查看文件

@@ -199,9 +199,6 @@ field_label_network_ssh_key=SSH Key
field_description_network_ssh_key=You can SSH into the Bubble with this key
message_network_ssh_key_do_not_install=Do not install any SSH key
field_label_send_metrics=Send error reports and usage statistics
field_label_newPaymentMethod=Add a Payment Method
field_label_existingPaymentMethod=Payment Method
err_noPaymentMethods=No payment methods are configured. Contact the administrator of this system.
msg_km_distance_away=km away
message_auto_detecting=Auto-Detecting... <small>(refresh page if this gets stuck)</small>
button_label_customize=Customize
@@ -597,19 +594,11 @@ err.mitm.changeInProgress=A change to MITM is already in progress
err.mitm.errorReadingControlFile=Error reading MITM control file
err.mitm.errorWritingControlFile=Error writing MITM control file
err.mitm.notInstalled=MITM component is not installed
err.name.invalid=Name is invalid
err.name.networkNameAlreadyExists=Name is already in use
err.name.regexFailed=Name must start with a letter and can only contain letters, numbers, hyphens, periods and underscores
err.node.name.alreadyExists=A node already exists with the same FQDN
err.node.cannotStopLocalNode=Cannot stop local Bubble
err.nodeOperationTimeout.required=Node operation timeout is required
err.nodeOperationTimeout.tooLong=Node operation timeout cannot be longer than 3 days
err.nodeOperationTimeout.tooShort=Node operation timeout cannot be shorter than 1 minute
err.name.length=Name is too long
err.name.tooShort=Name is too short
err.name.mismatch=Name mismatch
err.name.reserved=Name is reserved
err.name.alreadyInUse=Name is already in use
err.netlocation.invalid=Must specify both cloud and region, or neither
err.network.alreadyStarted=Network is already started
err.network.exists=A plan already exists for this network


+ 12
- 0
bubble-server/src/main/resources/message_templates/en_US/server/pre_auth/ResourceMessages.properties 查看文件

@@ -165,9 +165,17 @@ err.geoLocateService.notFound=GeoLocation service not found
err.app.notFound=App not found
err.name.required=Name is required
err.name.notFound=Account not found
err.name.length=Name is too long
err.name.tooShort=Name must be at least 4 characters
err.name.tooLong=Name cannot be longer than 100 characters
err.name.planMaxAccountLimit=No more accounts can be created on this plan. Upgrade your plan or delete some accounts.
err.name.alreadyInUse=Name is already in use
err.name.reservedForAccount=Name is already in use
err.name.reserved=Name is reserved
err.name.invalid=Name is invalid
err.name.networkNameAlreadyExists=Name is already in use
err.name.regexFailed=Name must start with a letter and can only contain letters, numbers, hyphens, periods and underscores
err.name.mismatch=Name mismatch
err.password.required=Password is required
err.password.tooShort=Password must be at least 8 characters
err.password.invalid=Password must contain at least one letter, one number, and one special character
@@ -266,6 +274,10 @@ message_login_agreeToTerms=By logging in, you agree to the <a target="_blank" re
message_login_authenticator_auth=Login requires Authenticator code
field_label_receiveInformationalMessages=Receive informational messages about your Bubble
field_label_receivePromotionalMessages=Receive news about Bubble, including new releases and new features
field_label_paymentMethod=Payment Method
field_label_newPaymentMethod=Add a Payment Method
field_label_existingPaymentMethod=Payment Method
err_noPaymentMethods=No payment methods are configured. Contact the administrator of this system.
button_label_login=Login
button_label_register=Register
button_label_forgotPassword=Forgot Password


正在加载...
取消
保存