Refactoring Utility di convalida della password

1

Data una password, sto provando a convalidare se passa tutte le regole di validazione come

  1. Sii lungo almeno 6 caratteri
  2. Contenere almeno una lettera (a-z o A-Z)
  3. Contiene almeno un numero (0-9)
  4. Contiene almeno un carattere speciale (@, $,%, ecc.)

Quindi sto creando una classe di convalida comune che può essere utilizzata in una qualsiasi delle mie applicazioni. Di seguito sono riportati i seguenti scenari che la classe di convalida deve gestire:

  • Passare la password, confermare la password come input ed eseguire tutte le convalide.
  • Passaggio della password corrente, nuova password, conferma password come input ed eseguire tutte le convalide.
  • Passa nome utente, password, conferma password come input ma salta convalida caratteri speciali

Quindi ecco la mia idea iniziale. Ho creato metodi statici per ogni scenario e restituito un oggetto Result che dirà se la convalida ha superato o fallito. Se non è riuscito, conterrà i codici di errore aggiunti all'oggetto lista errori che l'applicazione chiamante gestirà come necessario.

/* CASE1: Passing password, confirm password as input and perform all validation */ 
public static ValidationResult validate(final String newPassword, final String newConfirmedPassword) {
    ValidationResult result = checkPassword(null, newPassword, newConfirmedPassword, false, true);
    // check for any errors in result object
    return result;
}

/* CASE 2 : Passing current password, new password, confirm password as input and perform all validation */
public static ValidationResult validate(final String oldPassword, final String newPassword, final String newConfirmedPassword) {
    ValidationResult result = checkPassword(oldPassword, newPassword, newConfirmedPassword, true, true);
    // check for any errors in result object
    return result;
}

/* CASE3: Passing username, password, confirm password as input but skip special character validation  */
public static ValidationResult validate(final String userName, final String newPassword, final String newConfirmedPassword) {
    ValidationResult result = checkPassword(oldPassword, newPassword, newConfirmedPassword, true, false);
    // check for any errors in result object
    return result;
}

private static ValidationResult checkPassword(final String currentPass, final String newPass,
        final String confirmedPass, final boolean resetFlag, boolean allowSplChar) {
    ValidationResult result = new ValidationResult(true);
    if(resetFlag) {
        //check if current password app has entered is correct
        //check new password is different from current password
    }
    // check password length is between 8-14 characters 
    if (doesNotContainUpperCaseAlpha(newPass)){
        // set error code to result 
        result.getErrors().add("ERROR_NO_UPPERCASE");
    }
    if (doesNotContainLowerCaseAlpha(newPass)){
        // set error code to result 
        result.getErrors().add("ERROR_NO_LOWERCASE");
    }
    ...
    ..
    if(allowSplChar && doesNotContainSplCharacter(newPass)){
        // set error code to result 
        result.getErrors().add("ERROR_NO_SPECIAL_CHARAACTER");
    }
}

Il flusso sopra potrebbe funzionare per gli scenari richiesti, ma esiste un modo migliore per implementarlo?

    
posta Sachin 23.08.2016 - 20:04
fonte

1 risposta

2

Osservazioni:

  • Le firme del metodo sono troppo lunghe (5 parms!)
  • Tutti i metodi sono statici, possibile indicazione di una classe di Dio
  • Nessuna flessibilità considerando che si desidera ... una classe di convalida comune che può essere utilizzata in una delle mie applicazioni "
  • Le opzioni di convalida e le credenziali dell'utente sono miste (troppi dubbi)

Il mio suggerimento è:

  • Una classe o un'interfaccia PasswordValidator che è responsabile delle opzioni di convalida e di eseguire la convalida
  • Una classe di credenziali o un'interfaccia contenente nome utente, nuova password, ecc.
  • Uso: istanzia il validatore, imposta le impostazioni di convalida (forse un metodo Factory lo farebbe per te, puoi anche leggere le impostazioni di convalida da un file conf) quindi chiama validate(userCredentials);

Un PNG vale 1024 parole:

Stub e codice:

== > PasswordValidator.java < == Si potrebbe implementare validatori leggermente diversi. Se lo trovi troppo con un'interfaccia usa semplicemente la classe sotto.

public interface PasswordValidator {    
    public void setReset(boolean reset);
    public void setMinimalLength(int length);
    public void setAllowPasswordEqualsName(boolean allow);
    public void setAllowSpecialCharacters(boolean allow);

    public boolean getReset();
    public int getMinimalLength();
    public boolean getAllowPasswordEqualsName();
    public boolean getAllowSpecialCharacters();     
    public ValidationResult validate(Credentials cred);
}

== > Credentials.java < == Questo potrei essere una classe, ho usato un'interfaccia per risparmiare tempo e spazio

public interface Credentials {
    public void setUserName(String userName);
    public void setOldPasssword(String oldPassword);
    public void setNewPassword(String newPassword);
    public void setConfirmedNewPassword(String confirmedNewPassword);
    public String getUserName();
    public String getOldPasssword();
    public String getNewPassword();
    public String getConfirmedNewPassword();
}

== > ValidationResult.java < == Questa implementazione hai già

public class ValidationResult {
}

== > NicePasswordValidator.java < == Un implementatore di esempio di PasswordValidator

public class NicePasswordValidator implements PasswordValidator {

    private boolean allowSpecialCharacters;
    private boolean allowPasswordEqualsName;
    private int minimalLength;
    private boolean reset;  

    private static boolean containSpecialCharacters(String newPassword) {
        // TODO Auto-generated method stub
        return false;
    }

    private static boolean containsLowerCase(String newPassword) {
        // TODO Auto-generated method stub
        return false;
    }

    private static boolean containsUpperCase(String newPassword) {
        // TODO Auto-generated method stub
        return false;
    }

    private static boolean doesNotContainUpperCaseAlpha(String newPassword) {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public void setReset(boolean reset) {
        this.reset=reset;
    }

    @Override
    public void setMinimalLength(int length) {
        this.minimalLength=length;
    }

    @Override
    public void setAllowPasswordEqualsName(boolean allow) {
        this.allowPasswordEqualsName=allow;
    }

    @Override
    public void setAllowSpecialCharacters(boolean allow) {
        this.allowSpecialCharacters=allow;      
    }   

    @Override
    public boolean getReset() {
        return this.reset;
    }

    @Override
    public int getMinimalLength() {
        return this.minimalLength;
    }

    @Override
    public boolean getAllowPasswordEqualsName() {
        return this.allowPasswordEqualsName;
    }

    @Override
    public boolean getAllowSpecialCharacters() {
        return this.allowSpecialCharacters;
    }

    @Override
    public ValidationResult validate(Credentials cred) {

        ValidationResult result = new ValidationResult();

        if (!this.allowPasswordEqualsName && cred.getNewPassword().endsWith(cred.getUserName())){
            // add to result
        }

        if (!cred.getNewPassword().equals(cred.getConfirmedNewPassword())){
            // add to result
        }

        if (!this.containsUpperCase(cred.getNewPassword())){
            // add to result
        }

        if (!this.containsLowerCase(cred.getNewPassword())){
            // add to result
        }

        if (!this.getAllowSpecialCharacters() && this.containSpecialCharacters(cred.getNewPassword())){
            // add to result
        }

        return result;
    }
}
    
risposta data 23.08.2016 - 21:32
fonte

Leggi altre domande sui tag