use of org.springframework.shell.core.annotation.CliCommand in project cas by apereo.
the class AddPropertiesToConfigurationCommand method add.
/**
* Add properties to configuration.
*
* @param file the file
* @param group the group
* @throws Exception the exception
*/
@CliCommand(value = "add-properties", help = "Add properties associated with a CAS group/module to a Properties/Yaml configuration file.")
public void add(@CliOption(key = { "file" }, help = "Path to the CAS configuration file", unspecifiedDefaultValue = "/etc/cas/config/cas.properties", specifiedDefaultValue = "/etc/cas/config/cas.properties", optionContext = "Path to the CAS configuration file") final String file, @CliOption(key = { "group" }, specifiedDefaultValue = "", unspecifiedDefaultValue = "", help = "Group/module whose associated settings should be added to the CAS configuration file", optionContext = "Group/module whose associated settings should be added to the CAS configuration file", mandatory = true) final String group) throws Exception {
if (StringUtils.isBlank(file)) {
LOGGER.warn("Configuration file must be specified");
return;
}
final File filePath = new File(file);
if (filePath.exists() && (filePath.isDirectory() || !filePath.canRead() || !filePath.canWrite())) {
LOGGER.warn("Configuration file [{}] is not readable/writable or is not a path to a file", filePath.getCanonicalPath());
return;
}
final Map<String, ConfigurationMetadataProperty> results = findProperties(group);
LOGGER.info("Located [{}] properties matching [{}]", results.size(), group);
switch(FilenameUtils.getExtension(filePath.getName()).toLowerCase()) {
case "properties":
createConfigurationFileIfNeeded(filePath);
final Properties props = loadPropertiesFromConfigurationFile(filePath);
writeConfigurationPropertiesToFile(filePath, results, props);
break;
case "yml":
createConfigurationFileIfNeeded(filePath);
final Properties yamlProps = loadYamlPropertiesFromConfigurationFile(filePath);
writeYamlConfigurationPropertiesToFile(filePath, results, yamlProps);
break;
default:
LOGGER.warn("Configuration file format [{}] is not recognized", filePath.getCanonicalPath());
}
}
use of org.springframework.shell.core.annotation.CliCommand in project cas by apereo.
the class GenerateCryptoKeysCommand method generateKey.
/**
* Generate key.
*
* @param name the name
*/
@CliCommand(value = "generate-key", help = "Generate signing/encryption crypto keys for CAS settings")
public void generateKey(@CliOption(key = { "group" }, help = "Property group that holds the key (i.e. cas.webflow). The group must have a child category of 'crypto'.", mandatory = true, specifiedDefaultValue = "", unspecifiedDefaultValue = "", optionContext = "Property name for that holds the key") final String name) {
/*
Because the command is used both from the shell and CLI,
we need to validate parameters again.
*/
if (StringUtils.isBlank(name)) {
LOGGER.warn("No property/setting name is specified for signing/encryption key generation.");
return;
}
final CasConfigurationMetadataRepository repository = new CasConfigurationMetadataRepository();
final String cryptoGroup = name.concat(".crypto");
repository.getRepository().getAllGroups().entrySet().stream().filter(e -> e.getKey().startsWith(cryptoGroup)).forEach(e -> {
final ConfigurationMetadataGroup grp = e.getValue();
grp.getSources().forEach(Unchecked.biConsumer((k, v) -> {
final Object obj = ClassUtils.getClass(k, true).getDeclaredConstructor().newInstance();
if (obj instanceof EncryptionJwtSigningJwtCryptographyProperties) {
final EncryptionJwtSigningJwtCryptographyProperties crypto = (EncryptionJwtSigningJwtCryptographyProperties) obj;
LOGGER.info(cryptoGroup.concat(".encryption.key=" + EncodingUtils.generateJsonWebKey(crypto.getEncryption().getKeySize())));
LOGGER.info(cryptoGroup.concat(".signing.key=" + EncodingUtils.generateJsonWebKey(crypto.getSigning().getKeySize())));
} else if (obj instanceof EncryptionRandomizedSigningJwtCryptographyProperties) {
final EncryptionRandomizedSigningJwtCryptographyProperties crypto = (EncryptionRandomizedSigningJwtCryptographyProperties) obj;
final String encKey = new Base64RandomStringGenerator(crypto.getEncryption().getKeySize()).getNewString();
LOGGER.info(cryptoGroup.concat(".encryption.key=" + encKey));
LOGGER.info(cryptoGroup.concat(".signing.key=" + EncodingUtils.generateJsonWebKey(crypto.getSigning().getKeySize())));
}
}));
});
}
use of org.springframework.shell.core.annotation.CliCommand in project cas by apereo.
the class GenerateDdlCommand method generate.
/**
* Generate.
*
* @param file the file
* @param dialect the dialect
* @param delimiter the delimiter
* @param pretty the pretty
* @param dropSchema the drop schema
* @param createSchema the create schema
* @param haltOnError the halt on error
*/
@CliCommand(value = "generate-ddl", help = "Generate database DDL scripts")
public void generate(@CliOption(key = { "file" }, help = "DDL file to contain to generated script", specifiedDefaultValue = "/etc/cas/config/cas-db-schema.sql", unspecifiedDefaultValue = "/etc/cas/config/cas-db-schema.sql", optionContext = "DDL file to contain to generated script") final String file, @CliOption(key = { "dialect" }, help = "Database dialect class", specifiedDefaultValue = "HSQL", unspecifiedDefaultValue = "HSQL", optionContext = "Database dialect class") final String dialect, @CliOption(key = { "delimiter" }, help = "Delimiter to use for separation of statements when generating SQL", specifiedDefaultValue = ";", unspecifiedDefaultValue = ";", optionContext = "Delimiter to use for separation of statements when generating SQL") final String delimiter, @CliOption(key = { "pretty" }, help = "Format DDL scripts and pretty-print the output", specifiedDefaultValue = "true", unspecifiedDefaultValue = "true", optionContext = "Format DDL scripts and pretty-print the output") final boolean pretty, @CliOption(key = { "dropSchema" }, help = "Generate DROP SQL statements in the DDL", specifiedDefaultValue = "true", unspecifiedDefaultValue = "true", optionContext = "Generate DROP statements in the DDL") final boolean dropSchema, @CliOption(key = { "createSchema" }, help = "Generate DROP SQL statements in the DDL", specifiedDefaultValue = "true", unspecifiedDefaultValue = "true", optionContext = "Generate CREATE SQL statements in the DDL") final boolean createSchema, @CliOption(key = { "haltOnError" }, help = "Halt if an error occurs during the generation process", specifiedDefaultValue = "true", unspecifiedDefaultValue = "true", optionContext = "Halt if an error occurs during the generation process") final boolean haltOnError) {
final String dialectName = DIALECTS_MAP.getOrDefault(dialect.trim().toUpperCase(), dialect);
LOGGER.info("Using database dialect class [{}]", dialectName);
if (!dialectName.contains(".")) {
LOGGER.warn("Dialect name must be a fully qualified class name. Supported dialects by default are [{}] " + "or you may specify the dialect class directly", DIALECTS_MAP.keySet());
return;
}
final StandardServiceRegistryBuilder svcRegistry = new StandardServiceRegistryBuilder();
if (StringUtils.isNotBlank(dialectName)) {
svcRegistry.applySetting(AvailableSettings.DIALECT, dialect);
}
final MetadataSources metadata = new MetadataSources(svcRegistry.build());
REFLECTIONS.getTypesAnnotatedWith(MappedSuperclass.class).forEach(metadata::addAnnotatedClass);
REFLECTIONS.getTypesAnnotatedWith(Entity.class).forEach(metadata::addAnnotatedClass);
final SchemaExport export = new SchemaExport();
export.setDelimiter(delimiter);
export.setOutputFile(file);
export.setFormat(pretty);
export.setHaltOnError(haltOnError);
export.setManageNamespaces(true);
final SchemaExport.Action action;
if (createSchema && dropSchema) {
action = SchemaExport.Action.BOTH;
} else if (createSchema) {
action = SchemaExport.Action.CREATE;
} else if (dropSchema) {
action = SchemaExport.Action.DROP;
} else {
action = SchemaExport.Action.NONE;
}
LOGGER.info("Exporting Database DDL to [{}] using dialect [{}] with export type set to [{}]", file, dialect, action);
export.execute(EnumSet.of(TargetType.SCRIPT, TargetType.STDOUT), SchemaExport.Action.BOTH, metadata.buildMetadata());
LOGGER.info("Database DDL is exported to [{}]", file);
}
use of org.springframework.shell.core.annotation.CliCommand in project cas by apereo.
the class JasyptListProvidersCommand method listAlgorithms.
/**
* List providers you can use Jasypt.
* @param includeBC whether to include the BouncyCastle provider
*/
@CliCommand(value = "jasypt-list-providers", help = "List encryption providers with PBE Ciphers you can use with Jasypt")
public void listAlgorithms(@CliOption(key = { "includeBC" }, mandatory = false, help = "Include Bouncy Castle provider", specifiedDefaultValue = "true", unspecifiedDefaultValue = "false") final boolean includeBC) {
if (includeBC) {
if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
Security.addProvider(new BouncyCastleProvider());
}
} else {
Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME);
}
final Provider[] providers = Security.getProviders();
for (final Provider provider : providers) {
final Set<Provider.Service> services = provider.getServices();
final List<String> algorithms = services.stream().filter(service -> "Cipher".equals(service.getType()) && service.getAlgorithm().contains("PBE")).map(service -> service.getAlgorithm()).collect(Collectors.toList());
if (!algorithms.isEmpty()) {
LOGGER.info("Provider: Name: [{}] Class: [{}]", provider.getName(), provider.getClass().getName());
for (final String algorithm : algorithms) {
LOGGER.info(" - Algorithm: [{}]", algorithm);
}
}
}
}
use of org.springframework.shell.core.annotation.CliCommand in project cas by apereo.
the class JasyptTestAlgorithmsCommand method testAlgorithms.
/**
* List algorithms you can use Jasypt.
* @param includeBC whether to include the BouncyCastle provider
*/
@CliCommand(value = "jasypt-test-algorithms", help = "Test encryption alogrithms you can use with Jasypt to make sure encryption and decryption both work")
public void testAlgorithms(@CliOption(key = { "includeBC" }, mandatory = false, help = "Include Bouncy Castle provider", specifiedDefaultValue = "true", unspecifiedDefaultValue = "false") final boolean includeBC) {
final String[] providers;
if (includeBC) {
if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
Security.addProvider(new BouncyCastleProvider());
}
providers = new String[] { BouncyCastleProvider.PROVIDER_NAME, "SunJCE" };
} else {
Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME);
providers = new String[] { "SunJCE" };
}
LOGGER.info("==== JASYPT Password Based Encryption Algorithms ====\n");
final String password = "SecretKeyValue";
final String value = "ValueToEncrypt";
final Set<String> pbeAlgos = AlgorithmRegistry.getAllPBEAlgorithms();
for (final String provider : providers) {
for (final String algorithm : pbeAlgos) {
final CasConfigurationJasyptCipherExecutor cipher = new CasConfigurationJasyptCipherExecutor(this.environment);
cipher.setPassword(password);
cipher.setKeyObtentionIterations("1");
cipher.setAlgorithm(algorithm);
cipher.setProviderName(provider);
try {
final String encryptedValue;
try {
encryptedValue = cipher.encryptValuePropagateExceptions(value);
} catch (final EncryptionInitializationException e) {
// encryption doesn't work for this algorithm/provider combo
continue;
}
LOGGER.info("Provider: [{}] Algorithm: [{}]", provider, algorithm);
try {
cipher.decryptValuePropagateExceptions(encryptedValue);
LOGGER.info("Encrypted Value: [{}] Decryption Succeeded", encryptedValue);
} catch (final Exception e) {
LOGGER.info("Encrypted Value: [{}] Decryption Failed", encryptedValue);
}
} catch (final EncryptionInitializationException e) {
if (e.getCause() instanceof NoSuchAlgorithmException) {
LOGGER.info("Provider: [{}] does not support Algorithm: [{}]", provider, algorithm);
} else {
LOGGER.info("Error encrypting using provider: [{}] and algorithm: [{}], Message: {}", provider, algorithm, e.getMessage());
}
}
}
}
}
Aggregations