All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jclouds.util.PasswordGenerator Maven / Gradle / Ivy

The newest version!
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.jclouds.util;

import static shaded.com.google.common.base.Preconditions.checkArgument;

import java.security.SecureRandom;
import java.util.Collections;
import java.util.List;
import java.util.Random;

import shaded.com.google.common.base.Joiner;
import shaded.com.google.common.base.Strings;
import shaded.com.google.common.primitives.Chars;

/**
 * Generates random passwords.
 * 

* This class allows to configure the password requirements for: *

    *
  • Number of upper case and lower case letters
  • *
  • Inclusion of numbers
  • *
  • Inclusion of special characters
  • *
* By default, it will include at least three lower case letters, three upper * case, three numbers and three special characters, and a maximum of five from * each set. *

* It also allows to configure forbidden characters to accommodate the password * requirements for the different clouds. *

* Example usage: *

 * String password = new PasswordGenerator()
 *    .lower().count(3)  // Exactly three lower case characters
 *    .upper().count(2)  // Exactly 2 upper case characters 
 *    .numbers().min(5).exclude("012345".toCharArray()) // At least five numbers, from 6 to 9.
 *    .symbols().min(6).max(10) // Between 6 and 10 special characters
 *    .generate();
 * 
* */ public class PasswordGenerator { private static final Random RANDOM = new SecureRandom(); private final Config lower = new Config("abcdefghijklmnopqrstuvwxyz").min(3).max(5); private final Config upper = new Config("ABCDEFGHIJKLMNOPQRSTUVWXYZ").min(3).max(5); private final Config numbers = new Config("1234567890").min(3).max(5); // Use a small set of symbols that does not break shell commands private final Config symbols = new Config("~@#%*()-_=+:,.?").min(3).max(5); /** * Returns the lower case configuration. Allows to configure the presence of lower case characters. */ public Config lower() { return lower; } /** * Returns the upper case configuration. Allows to configure the presence of upper case characters. */ public Config upper() { return upper; } /** * Returns the numbers configuration. Allows to configure the presence of numeric characters. */ public Config numbers() { return numbers; } /** * Returns the special character configuration. Allows to configure the presence of special characters. */ public Config symbols() { return symbols; } /** * Generates a random password using the configured spec. */ public String generate() { StringBuilder sb = new StringBuilder(); sb.append(lower.fragment()); sb.append(upper.fragment()); sb.append(numbers.fragment()); sb.append(symbols.fragment()); return shuffleAndJoin(sb.toString().toCharArray()); } private static String shuffleAndJoin(char[] chars) { List result = Chars.asList(chars); Collections.shuffle(result); return Joiner.on("").join(result); } public class Config { private final String characters; private char[] exclusions; private int minLength; private int maxLength; private Config(String characters) { checkArgument(!Strings.isNullOrEmpty(characters), "charactets must be a non-empty string"); this.characters = characters; } public Config exclude(char[] exclusions) { this.exclusions = exclusions; return this; } public Config min(int num) { this.minLength = num; return this; } public Config max(int num) { this.maxLength = num; return this; } public Config count(int num) { min(num); max(num); return this; } private String fragment() { int length = minLength + RANDOM.nextInt((maxLength - minLength) + 1); return new Generator(characters, length, exclusions).generate(); } // Delegate to enclosing class for better fluent generators public Config lower() { return PasswordGenerator.this.lower(); } public Config upper() { return PasswordGenerator.this.upper(); } public Config numbers() { return PasswordGenerator.this.numbers(); } public Config symbols() { return PasswordGenerator.this.symbols(); } public String generate() { return PasswordGenerator.this.generate(); } } private static class Generator { private final char[] characters; private final int count; private Generator(String characters, int count, char[] exclusions) { checkArgument(!Strings.isNullOrEmpty(characters), "charactets must be a non-empty string"); this.count = count; if (exclusions == null || exclusions.length == 0) { this.characters = characters.toCharArray(); } else { this.characters = characters.replaceAll("[" + new String(exclusions) + "]", "").toCharArray(); } } public String generate() { char[] selected = new char[count]; for (int i = 0; i < count; i++) { selected[i] = characters[RANDOM.nextInt(characters.length)]; } return shuffleAndJoin(selected); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy