X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fusermanager%2Fapi%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fusermanager%2FUserConfig.java;h=0c14dea38a4a9ff69993d1e6a88503ceb5db0792;hb=468552562af9a4192426000ebeff637d029b006f;hp=cca194e95337e30877aaff50332e37e6df4be30f;hpb=355298472cafe51d7b32f6071f3927b9122d9c16;p=controller.git diff --git a/opendaylight/usermanager/api/src/main/java/org/opendaylight/controller/usermanager/UserConfig.java b/opendaylight/usermanager/api/src/main/java/org/opendaylight/controller/usermanager/UserConfig.java index cca194e953..0c14dea38a 100644 --- a/opendaylight/usermanager/api/src/main/java/org/opendaylight/controller/usermanager/UserConfig.java +++ b/opendaylight/usermanager/api/src/main/java/org/opendaylight/controller/usermanager/UserConfig.java @@ -18,35 +18,71 @@ import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + import org.opendaylight.controller.sal.authorization.AuthResultEnum; import org.opendaylight.controller.sal.utils.HexEncode; import org.opendaylight.controller.sal.utils.Status; import org.opendaylight.controller.sal.utils.StatusCode; -import org.opendaylight.controller.usermanager.AuthResponse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Configuration Java Object which represents a Local AAA user configuration * information for User Manager. */ +@XmlRootElement +@XmlAccessorType(XmlAccessType.NONE) public class UserConfig implements Serializable { private static final long serialVersionUID = 1L; - - protected String user; - protected List roles; - private String password; + private static Logger log = LoggerFactory.getLogger(UserConfig.class); + private static final boolean strongPasswordCheck = Boolean.getBoolean("enableStrongPasswordCheck"); + private static final String DIGEST_ALGORITHM = "SHA-384"; + private static final String BAD_PASSWORD = "Bad Password"; private static final int USERNAME_MAXLENGTH = 32; - private static final int PASSWORD_MINLENGTH = 5; - private static final int PASSWORD_MAXLENGTH = 256; + protected static final String PASSWORD_REGEX = "(?=.*[^a-zA-Z0-9])(?=.*\\d)(?=.*[a-z])(?=.*[A-Z]).{8,256}$"; private static final Pattern INVALID_USERNAME_CHARACTERS = Pattern.compile("([/\\s\\.\\?#%;\\\\]+)"); - private static MessageDigest oneWayFunction = null; + private static MessageDigest oneWayFunction; + static { try { - UserConfig.oneWayFunction = MessageDigest.getInstance("SHA-1"); + UserConfig.oneWayFunction = MessageDigest.getInstance(DIGEST_ALGORITHM); } catch (NoSuchAlgorithmException e) { - e.printStackTrace(); + log.error(String.format("Implementation of %s digest algorithm not found: %s", DIGEST_ALGORITHM, + e.getMessage())); } } + /** + * User Id + */ + @XmlElement + protected String user; + + /** + * List of roles a user can have + * example + * System-Admin + * Network-Admin + * Network-Operator + */ + @XmlElement + protected List roles; + + /** + * Password + * Should be 8 to 256 characters long, + * contain both upper and lower case letters, at least one number, + * and at least one non alphanumeric character. + */ + @XmlElement + private String password; + + + public UserConfig() { } @@ -63,16 +99,12 @@ public class UserConfig implements Serializable { public UserConfig(String user, String password, List roles) { this.user = user; - this.password = password; - if (this.validatePassword().isSuccess()) { - /* - * Only if the password is a valid one, hash it. So in case it is not - * valid, when UserConfig.validate() is called, the proper - * validation error will be returned to the caller. If we hashed a - * priori instead, the mis-configuration would be masked - */ - this.password = hash(this.password); - } + /* + * Password validation to be done on clear text password. If fails, mark + * the password with a well known label, so that object validation can + * report the proper error. Only if password is a valid one, hash it. + */ + this.password = (validatePassword(password).isSuccess()) ? hash(password) : BAD_PASSWORD; this.roles = (roles == null) ? new ArrayList() : new ArrayList(roles); } @@ -142,12 +174,15 @@ public class UserConfig implements Serializable { } public Status validate() { - Status validCheck = validateRoles(); + Status validCheck = validateUsername(); if (validCheck.isSuccess()) { - validCheck = validateUsername(); + validCheck = (!password.equals(BAD_PASSWORD)) ? new Status(StatusCode.SUCCESS) : new Status( + StatusCode.BADREQUEST, + "Password should be 8 to 256 characters long, contain both upper and lower case letters, " + + "at least one number and at least one non alphanumeric character"); } if (validCheck.isSuccess()) { - validCheck = validatePassword(); + validCheck = validateRoles(); } return validCheck; } @@ -168,15 +203,15 @@ public class UserConfig implements Serializable { return new Status(StatusCode.SUCCESS); } - private Status validatePassword() { + private Status validatePassword(String password) { if (password == null || password.isEmpty()) { return new Status(StatusCode.BADREQUEST, "Password cannot be empty"); } - if (password.length() < UserConfig.PASSWORD_MINLENGTH - || password.length() > UserConfig.PASSWORD_MAXLENGTH) { - return new Status(StatusCode.BADREQUEST, - "Password should have 5-256 characters"); + if (strongPasswordCheck && !password.matches(UserConfig.PASSWORD_REGEX)) { + return new Status(StatusCode.BADREQUEST, "Password should be 8 to 256 characters long, " + + "contain both upper and lower case letters, at least one number " + + "and at least one non alphanumeric character"); } return new Status(StatusCode.SUCCESS); } @@ -247,4 +282,25 @@ public class UserConfig implements Serializable { UserConfig.oneWayFunction.reset(); return HexEncode.bytesToHexString(UserConfig.oneWayFunction.digest(message.getBytes(Charset.defaultCharset()))); } + + /** + * Returns UserConfig instance populated with the passed parameters. It does + * not run any checks on the passed parameters. + * + * @param userName + * the user name + * @param password + * the plain text password + * @param roles + * the list of roles + * @return the UserConfig object populated with the passed parameters. No + * validity check is run on the input parameters. + */ + public static UserConfig getUncheckedUserConfig(String userName, String password, List roles) { + UserConfig config = new UserConfig(); + config.user = userName; + config.password = hash(password); + config.roles = roles; + return config; + } }