package org.apereo.cas.shell.commands;

import org.apache.commons.lang3.ClassUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.apereo.cas.configuration.model.core.util.EncryptionJwtSigningJwtCryptographyProperties;
import org.apereo.cas.configuration.model.core.util.EncryptionRandomizedSigningJwtCryptographyProperties;
import org.apereo.cas.metadata.CasConfigurationMetadataRepository;
import org.apereo.cas.shell.cli.CommandLineOptions;
import org.apereo.cas.util.EncodingUtils;
import org.apereo.cas.util.RegexUtils;
import org.jooq.lambda.Unchecked;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.configurationmetadata.ConfigurationMetadataGroup;
import org.springframework.boot.configurationmetadata.ConfigurationMetadataProperty;
import org.springframework.shell.core.CommandMarker;
import org.springframework.shell.core.annotation.CliCommand;
import org.springframework.shell.core.annotation.CliOption;
import org.springframework.stereotype.Service;

/**
 * This is {@link GenerateKeyCommand}.
 *
 * @author Misagh Moayyed
 * @since 5.2.0
 */
@Service
public class GenerateKeyCommand implements CommandMarker {
    private static final Logger LOGGER = LoggerFactory.getLogger(GenerateKeyCommand.class);

    /**
     * Find property.
     *
     * @param name the name
     */
    @CliCommand(value = "generate-key", help = "Generate keys for CAS settings")
    public void generateKey(
            @CliOption(key = {"name"},
                    help = "Property name for that holds the key",
                    optionContext = "Property name for that holds the key",
                    mandatory = true) 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 key generation.");
            return;
        }

        final CasConfigurationMetadataRepository repository =
                new CasConfigurationMetadataRepository(
                        "file:/Users/Misagh/Workspace/GitWorkspace/cas-server/core/cas-server-core-configuration/build/classes/java/main/META-INF/spring" +
                                "-configuration-metadata.json");
        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).newInstance();
                                if (obj instanceof EncryptionJwtSigningJwtCryptographyProperties) {
                                    final EncryptionJwtSigningJwtCryptographyProperties crypto = (EncryptionJwtSigningJwtCryptographyProperties) obj;
                                    LOGGER.info(cryptoGroup.concat(".encryption.key=").concat(EncodingUtils.generateJsonWebKey(crypto.getEncryption().getKeySize())));
                                    LOGGER.info(cryptoGroup.concat(".signing.key=").concat(EncodingUtils.generateJsonWebKey(crypto.getSigning().getKeySize())));
                                } else if (obj instanceof EncryptionRandomizedSigningJwtCryptographyProperties) {
                                    final EncryptionRandomizedSigningJwtCryptographyProperties crypto = (EncryptionRandomizedSigningJwtCryptographyProperties) obj;
                                    LOGGER.info(cryptoGroup.concat(".encryption.key=").concat(RandomStringUtils.randomAlphanumeric(crypto.getEncryption().getKeySize())));
                                    LOGGER.info(cryptoGroup.concat(".signing.key=").concat(EncodingUtils.generateJsonWebKey(crypto.getSigning().getKeySize())));
                                }
                            }));
                });
    }
}

@@ -471,112 +471,21 @@
 cas.
-shell.cli.CommandLineOptions;%0Aimport org.apereo.cas.util.EncodingUtils;%0Aimport org.apereo.cas.util.Regex
+util.Encoding
 Util
@@ -664,93 +664,8 @@
 up;%0A
-import org.springframework.boot.configurationmetadata.ConfigurationMetadataProperty;%0A
 impo
@@ -1265,16 +1265,42 @@
 enerate 
+signing/encryption crypto 
 keys for
@@ -1375,20 +1375,21 @@
 key = %7B%22
-name
+group
 %22%7D,%0A    
@@ -1417,32 +1417,29 @@
 = %22Property 
-name for
+group
  that holds 
@@ -1437,32 +1437,238 @@
 at holds the key
+ (i.e. cas.webflow). The group must have a child category of 'crypto'.%22,%0A                    mandatory = true,%0A                    specifiedDefaultValue = %22%22,%0A                    unspecifiedDefaultValue = %22
 %22,%0A             
@@ -1732,46 +1732,8 @@
 key%22
-,%0A                    mandatory = true
 ) fi
@@ -2002,16 +2002,35 @@
 ied for 
+signing/encryption 
 key gene
@@ -2132,32 +2132,16 @@
 sitory =
-%0A               
  new Cas
@@ -2176,227 +2176,8 @@
 ory(
-%0A                        %22file:/Users/Misagh/Workspace/GitWorkspace/cas-server/core/cas-server-core-configuration/build/classes/java/main/META-INF/spring%22 +%0A                                %22-configuration-metadata.json%22
 );%0A 
@@ -2549,37 +2549,8 @@
 s().
-%0A                            
 forE
@@ -2606,32 +2606,24 @@
             
-    
-    
 final Object
@@ -2697,24 +2697,16 @@
         
-       
- 
 if (obj 
@@ -2761,32 +2761,24 @@
 operties) %7B%0A
-        
             
@@ -2931,32 +2931,24 @@
             
-  
-      
 LOGGER.info(
@@ -2980,33 +2980,27 @@
 yption.key=%22
-).concat(
+ + 
 EncodingUtil
@@ -3084,32 +3084,24 @@
             
-    
-    
 LOGGER.info(
@@ -3130,33 +3130,27 @@
 igning.key=%22
-).concat(
+ + 
 EncodingUtil
@@ -3231,24 +3231,16 @@
         
-      
-  
 %7D else i
@@ -3309,32 +3309,24 @@
 operties) %7B%0A
-        
             
@@ -3493,32 +3493,24 @@
             
-        
 LOGGER.info(
@@ -3546,25 +3546,19 @@
 on.key=%22
-).concat(
+ + 
 RandomSt
@@ -3650,32 +3650,24 @@
             
-        
 LOGGER.info(
@@ -3704,17 +3704,11 @@
 ey=%22
-).concat(
+ + 
 Enco
@@ -3801,26 +3801,10 @@
     
-        %7D%0A        
+%7D%0A
     

clean up shell usage