Strukturerte feilmeldinger ved passordvalidering

Spesifikasjon av hvordan Cerebrum og Brukerinfo kan gi strukturert oversikt over hvilke passord- eller passfraseregler som passerer.

1   Hva er poenget med dette?

  • Vi ønsker å gi en bruker som forsøker å bytte passord en strukturert oversikt over hvilke regler et passord/en passfrase validerer mot.
  • Vi ønsker å kunne skille mellom feilmeldinger for passord og passfraser, slik at det er tydelig for brukeren hvilket regelsett som legges til grunn.
  • Vi ønsker å kunne gjengi disse feilmeldingene på ulike språk.

2   Hvordan henger dette sammen i dag?

Ved validering av passord kalles account.password_good_enough, som i core-API-et ikke gjør noe som helst. Passordregler legges til ved å lage en mixin til account-klassen som gjør en sjekk og kaster en PasswordNotGoodEnough-exception hvis passordet ikke validerer. Hvis ingen av passordsjekkene kaster exception, er passordet gyldig.

Feilmeldingene er hardkodet på ett språk, og PasswordNotGoodEnough kastes selv om det er snakk om en passfrase som ikke validerer. Når en mixin har kastet exception, kalles ikke sjekkene som er lenger opp i kjeden.

3   Hvordan i alle dager løser vi dette?

  • Mixins endres slik at de ikke erstatter password_good_enough, men på et vis registrerer sin eksistens for account-klassen.
  • Som standard kaller password_good_enough én og én valideringsmetode frem til den kommer over en som ikke passerer. Exception kastes.
  • Ved å fortelle password_good_enough at man ønsker en strukturert oversikt, kalles alle valideringsmetodene. Strukturert oversikt returneres.
  • Feilmeldingene som returneres fra sjekkene oversettes ved hjelp av gettext.

4   Hva slags struktur? Hæ? Vær litt konkret!

Strukturen vil typisk sendes til klientene i JSON-format. Da kan det se f.eks. slik ut for strenger 'siM5meoan1234':

{
    "style": "rigid",
    "checks": {
        "phrase": [
            {
                "length": {
                    "requirement": {
                        "nb": "Må være minst 12 tegn langt.",
                        "en": "Must be at least 12 characters."
                    },
                    "errors": null,
                    "passed": true
                }
            },
            {
                "num_words": {
                    "requirement": {
                        "nb": "Må bestå av minst 4 ord av lengde 2.",
                        "en": "Must contain at least 4 words of length 2."
                    },
                    "errors": {
                        "nb": [
                            "Passordet må bestå av minst 4 ord av lengde 2"
                        ],
                        "en": [
                            "Password must have at least 4 words of length 2"
                        ]
                    },
                    "passed": false
                }
            },
            {
                "avg_word_length": {
                    "requirement": {
                        "nb": "Ord må ha gjennomsnittlig lenge av 4 tegn.",
                        "en": "Words must be in average at least 4 characters long."
                    },
                    "errors": null,
                    "passed": true
                }
            }
        ],
        "rigid": [
            {
                "length": {
                    "requirement": {
                        "nb": "Må minst 8 tegn langt.",
                        "en": "Must be at least 8 characters."
                    },
                    "errors": null,
                    "passed": true
                }
            },
            {
                "ascii_characters_only": {
                    "requirement": {
                        "nb": "Kan inneholde kun ASCII-bokstaver, siffer og: !\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
                        "en": "Can contain only ASCII letters, digits and: !\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"
                    },
                    "errors": null,
                    "passed": true
                }
            },
            {
                "space_or_null": {
                    "requirement": {
                        "nb": "Må ikke inneholde mellomrom eller et tomt (null) tegn.",
                        "en": "Must not contain a space or the special null character."
                    },
                    "errors": null,
                    "passed": true
                }
            },
            {
                "multiple_character_sets": {
                    "requirement": {
                        "nb": "Noe",
                        "en": "Something"
                    },
                    "errors": null,
                    "passed": true
                }
            },
            {
                "character_sequence": {
                    "requirement": {
                        "nb": "Må ikke inneholde sekvenser av relaterte tegn.",
                        "en": "Must not contain sequences of closely related characters."
                    },
                    "errors": {
                        "nb": [
                            "Passordet må ikke inneholde tegn i alfabetisk eller numerisk rekkefølge",
                            "Passordet må ikke inneholde sekvenser av tegn som er geometrisk relatert på tastaturet (f.eks. qwerty)"
                        ],
                        "en": [
                            "Password cannot contain characters in alpabetical or numerical order",
                            "Password cannot contain neighbouring keyboard keys"
                        ]
                    },
                    "passed": false
                }
            },
            {
                "repeated_pattern": {
                    "requirement": {
                        "nb": "Må ikke inneholde gjentagende sekvenser.",
                        "en": "Must not contain repeated sequences of characters."
                    },
                    "errors": null,
                    "passed": true
                }
            },
            {
                "username": {
                    "requirement": {
                        "nb": "Må ikke inneholde brukernavnet ditt, ikke engang baklengs.",
                        "en": "Must not contain your username, even in reverse."
                    },
                    "errors": null,
                    "passed": true
                }
            },
            {
                "owner_name": {
                    "requirement": {
                        "nb": "Må ikke inneholde 5 eller flere tegn fra navnet ditt.",
                        "en": "Must not contain 5 or more characters from your name."
                    },
                    "errors": {
                        "nb": [
                            "Passordet må ikke inneholde ditt navn."
                        ],
                        "en": [
                            "Password cannot contain your name."
                        ]
                    },
                    "passed": false
                }
            },
            {
                "history": {
                    "requirement": {
                        "nb": "Må ikke likne på et gammelt passord.",
                        "en": "Must not be too similar to an old password."
                    },
                    "errors": null,
                    "passed": true
                }
            },
            {
                "dictionary": {
                    "requirement": {
                        "nb": "Må ikke inneholde ord som du finner i ordliste",
                        "en": "Must not contain dictionary words."
                    },
                    "errors": null,
                    "passed": true
                }
            }
        ]
    },
    "passed": false,
    "allowed_style": "mixed"
}

der:

  • 'style' er passordtypen slik som Cerebrum oppfatter den. Kan være 'rigid' eller 'phrase'
  • 'checks' inneholder testliste for passord ('rigid') og / eller passfraser ('phrase')
  • 'passed' hvorvidt Cerebrum anser strenger som gyldig passord / passfrase
  • 'allowed_style' hvilke passordtyper støttes. Kan være 'rigid', 'phrase' eller 'mixed'.

Hver test i listen inneholder navn, karv (requirement), feil (errors) dersom den feilet og test status ('passed')

Av jbr
Publisert 22. mars 2016 13:43