/******************************************************************************* * Copyright (c) 2012-2017 Codenvy, S.A. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Codenvy, S.A. - initial API and implementation *******************************************************************************/ package org.eclipse.che.account.spi; import org.eclipse.che.account.api.AccountManager; import org.eclipse.che.api.core.NotFoundException; import org.eclipse.che.api.core.ServerException; import org.eclipse.che.commons.lang.NameGenerator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.inject.Inject; import javax.inject.Singleton; import java.util.regex.Pattern; /** * Utils for account validation. * * @author Sergii Leschenko */ // TODO extract normalization code from the validator as it is not related to the validation at all @Singleton public class AccountValidator { private static final Logger LOG = LoggerFactory.getLogger(AccountValidator.class); private static final Pattern ILLEGAL_ACCOUNT_NAME_CHARACTERS = Pattern.compile("[^a-zA-Z0-9-]" + // all character except allowed "|(?<=-)-+" + // non single hyphens "|^-+" + // hyphens at the beginning "|-+$"); // hyphens at the end private static final Pattern VALID_ACCOUNT_NAME = Pattern.compile("^(?:[a-zA-Z0-9]-?)*[a-zA-Z0-9]+"); private final AccountManager accountManager; @Inject public AccountValidator(AccountManager accountManager) { this.accountManager = accountManager; } /** * Validate name, if it doesn't contain illegal characters * * @param name * account name * @return true if valid name, false otherwise */ public boolean isValidName(String name) { return name != null && VALID_ACCOUNT_NAME.matcher(name).matches(); } /** * Remove illegal characters from account name, to make it URL-friendly. * If all characters are illegal, return automatically generated account name with specified prefix. * Also ensures account name is unique, if not, adds digits to it's end. * * @param name * account name * @param prefix * prefix to add to generated name * @return account name without illegal characters */ public String normalizeAccountName(String name, String prefix) throws ServerException { String normalized = ILLEGAL_ACCOUNT_NAME_CHARACTERS.matcher(name).replaceAll(""); String candidate = normalized.isEmpty() ? NameGenerator.generate(prefix, 4) : normalized; int i = 1; try { while (accountExists(candidate)) { candidate = normalized.isEmpty() ? NameGenerator.generate(prefix, 4) : normalized + String.valueOf(i++); } } catch (ServerException e) { LOG.warn("Error occurred during account name normalization", e); throw e; } return candidate; } private boolean accountExists(String accountName) throws ServerException { try { accountManager.getByName(accountName); } catch (NotFoundException e) { return false; } return true; } }